[DESAFIO] NodeJS mais rápido que o Bun v1.0.1

Uma nova runtime de Javascript foi lançada esse mês o Bun e provavelmente tu já sabe. Eu sempre testo performance usando algoritmo basico e assim como fiz pro Mojo vs. Python escolhi fazer Fibonacci.

Eis que o Bun ficou MUITO atras do NodeJS: Video nesse Tweet.

Me ajude a descobrir onde está a perda de performance do Bun.

console.time("Execution Time");
const n = 1000000
let a = BigInt(0), b = BigInt(1); // fixed
for (let i = BigInt(0); i < n; i++) {
  [a, b] = [b, a + b];
}
console.log("fib: " + a);
console.timeEnd("Execution Time");

Adicionando misterio a essa desafio:

Se fizer o loop a seguir sem a matematica do Fibonacci o Bun desempenha melhor que o NodeJS.

console.time("Execution Time");
const n = 1000000
for (let i = BigInt(0); i < n; i++) {
    console.log("Item: " + i);
}
console.timeEnd("Execution Time");

Ambiente que rodei o teste MacOS

  • Apple Chip M1
  • Apple Chip M1 Max

Nota: Obviamente rodei o mesmo codigo em ambos e não usei nenhuma biblioteca externa apenas o raw Javacript que o DHH tanto ama.

Fiz alguns testes aqui, só fiz uma pequena modificação no código, inicializando o n com um BigInt também:

let n = 1000000n; // sufixo "n" faz com que seja BigInt
let a = BigInt(0), b = BigInt(1);
for (let i = BigInt(0); i < n; i++) {
  [a, b] = [b, a + b];
}
console.log(a);

Testei na minha máquina (Ubuntu 22.04.3, processador 11th Gen Intel® Core™ i5-1145G7 2.60GHz, 8 núcleos), primeiro com o teste mais básico, usando o comando time do Linux. Ou seja, time bun run arquivo.js e time node arquivo.js. A versão do Node é v18.17.1, e do Bun é 1.0.1. Os resultados estão abaixo (lembrando que em outros hardwares os tempos poderão ser diferentes, obviamente), só retirei a saída do console.log para não deixar poluído.

Node:

real    0m10,368s
user    0m8,712s
sys     0m0,037s

Bun:

real    0m9,915s
user    0m9,782s
sys     0m1,833s

O que importa é a primeira linha ("real", o tempo que efetivamente se passou entre eu teclar ENTER e o comando terminar).

Só de curiosidade, "user" é o tempo de CPU em user mode (fora do kernel), e "sys" é o tempo de CPU dentro do kernel (em chamadas de sistema, por exemplo). Mas estes tempos são computados considerando todos os núcleos, então se a máquina tem mais de um, a soma de "user" e "sys" pode ser maior que "real", conforme explicado aqui.

Enfim, no meu caso o Node demorou um pouco mais, mas dado o tempo total de ambos (10,3 segundos versus 9,9 segundos), não acho que foi uma diferença tão significativa (cerca de 4% a mais).


Mas tem um detalhe, operações de I/O (como o console.log) costumam ser caras e elas geralmente acabam mascarando o resultado (neste caso nem tanto porque só tem uma, mas enfim). Então removi o console.log para ver apenas o tempo do loop e rodei de novo.

Node:

real    0m8,615s
user    0m8,577s
sys     0m0,033s

Bun:

real    0m9,329s
user    0m9,424s
sys     0m1,710s

Agora o Bun foi ligeiramente mais lento, mas novamente, não acho que a diferença é tão significativa.

Testei mais algumas vezes, e às vezes o Node era mais rápido, às vezes era mais lento, mas sempre com diferenças pequenas. Nada tão gritante quanto o que vc encontrou.


Uma maneira melhor de testar

O problema de fazer um teste isolado é justamente esse: vc roda uma vez um pequeno trecho de código e já acha que é o suficiente, mas conforme já visto aqui, isso pode levar a conclusões precipitadas.

Mesmo que rode várias vezes, podem ter outros fatores que influenciam, como outros processos rodando na mesma máquina (ainda mais se tiver I/O e outras operações bloqueantes), e até mesmo a própria inicialização do runtime (tanto o Node quanto o Bun precisam de uma etapa de inicialização antes de começar a rodar o código propriamente dito).

Sendo assim, uma forma melhor de testar seria usar uma lib específica que desconsidera esses fatores externos. Eu usei o Benchmark.js, o código ficou assim:

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;

suite.add('test', function () {
    let n = 1000000n;
    let a = BigInt(0), b = BigInt(1);
    for (let i = BigInt(0); i < n; i++) {
      [a, b] = [b, a + b];
    }
}).on('cycle', function (event) {
    console.log(String(event.target));
}).run({
    'async': true
});

Obs: o propósito do Benchmark.js na verdade é comparar dois códigos diferentes. Por exemplo, chamo várias vezes add com algoritmos diferentes, e no final ele mostra qual é mais rápido. Mas aqui eu coloquei apenas um, e rodei este teste no Node e depois no Bun, pois ele também mostra a quantidade de operações por segundo que conseguiu executar. E é exatamente isso que eu quero comparar, pois dá para ter uma ideia melhor do desempenho de cada um.

Resultados com Node:

test x 0.12 ops/sec ±0.24% (5 runs sampled)

E com Bun:

test x 0.11 ops/sec ±0.90% (5 runs sampled)

Ou seja, 0,12 operações por segundo versus 0,11 operações por segundo. Em outras palavras, no Node demoraria cerca de 8,3 segundos para rodar o código uma vez, e no Bun, cerca de 9 segundos. Mais uma vez, uma diferença bem pequena, nada da discrepância que vc encontrou.

Rodei mais algumas vezes e os resultados giraram em torno disso, com pouca variação, e às vezes um era melhor, às vezes o outro - o que mostra que mesmo uma lib que desconsidera fatores externos não consegue eliminar 100% deles.


Quanto ao segundo caso (o console.log dentro do loop), realmente o Node foi pior em todos os casos. Primeiro com time, segue abaixo.

Bun:

real    0m2,648s
user    0m0,656s
sys     0m1,416s

Node:

real    0m5,264s
user    0m4,276s
sys     0m0,884s

E com o Benchmark.js:

Bun:

test x 0.38 ops/sec ±2.40% (5 runs sampled)

Node:

test x 0.19 ops/sec ±7.30% (5 runs sampled)

Ou seja, o Bun foi cerca de duas vezes mais rápido, uma diferença maior que no primeiro código.

Pesquisei um pouco a respeito e encontrei isso, que indica que a implementação do console.log no Node acaba deixando-o pior para este caso específico.


Conclusões (ou não)

No fim das contas, é difícil tirar conclusões definitivas sobre qual deles sempre será mais rápido. Isso depende de tantos fatores que o melhor a fazer é testar em uma situação mais próxima possível do caso concreto: teste o seu sistema, com seu código e seus casos de uso, e veja se faz diferença. Testar rodando um código qualquer uma ou poucas vezes é o teste mais ingênuo e propenso a erros que vc pode fazer (e tirar "verdades" disso é pior ainda). Testar a situação real costuma ser mais efetivo, pois aí vc está considerando o seu contexto específico em vez de só seguir a moda. Mais ainda, como vimos acima, em um caso particular pode fazer mais diferença que em outros, então o melhor é testar com o código que vc efetivamente vai usar.

Se procurar por benchmarks que comparam os dois, vai encontrar vários diferentes, e é importante ver qual código foi usado para testar, já que isso pode fazer diferença. E claro que também precisa considerar outros fatores: se usar A ou B vai facilitar o dia-a-dia da sua equipe, se é estável, se aguenta o tranco, etc etc etc. Vc pode inclusive concluir que não faz diferença, e não tem problema, pois o que importa é que seja uma decisão embasada, em vez de só puro achismo ou "ouvi dizer que é melhor".

Exato! Foi um typo porque eu reescrevi o Fibonacci enquanto postava aqui :) `b = BigInt(1)` **PRIMEIRAMENTE: MUITO MASSA A TUA ANALISE!** Eu vou postar um video amanhã sobre e vou colocar o link do TabNews nele porque acredito que até amanhã conseguimos chegar na conclusão do porque o NodeJS performa muito mais rapido que o Bun (todas as vezes aqui) no meu ambiente com um **MacOS M1 Max**. Não usei nenhuma biblioteca, apenas usei de fato o `console.log` e um `console.time`. Eu vou rodar o `Benchmark.Suite;` aqui e postar como que ficou no **M1**.
O resultado aqui no **M1 Max** foi bem diferente. ``` rinha % bun execute.js test x 3.80 ops/sec ±5.63% (14 runs sampled) rinha % node execute.js test x 12.14 ops/sec ±3.39% (35 runs sampled) ``` Rodei multiplas vezes em todas o bun ficava em 3-4 ops/sec enquanto o Node ficava em 11-12 ops/sec, confirmando que no meu **M1 Max** rodando o mesmo teste que você o Node performou 3x-4x mais rapido que bun. Seria interessante alguem com **Apple Chip M1** fazer o mesmo testes, e talvez alguem com MacOs Intel Chip.
Eu tenho um MacBook antigo (2012), processador 2.6 GHz Quad-Core Intel Core i7, e refiz o teste nele com as mesmas versões (Node 18.17.1 e Bun 1.0.1). Agora a diferença foi bem maior no código que calcula Fibonacci. Primeiro com `time`: Node: ``` real 0m9.818s user 0m9.412s sys 0m0.443s ``` Bun: ``` real 0m33.275s user 0m33.062s sys 0m3.324s ``` E com o Benchmark.js: Node: ``` test x 0.14 ops/sec ±1.67% (5 runs sampled) ``` Bun: ``` test x 0.03 ops/sec ±0.36% (5 runs sampled) ``` --- Já com o segundo código (`console.log` dentro do *loop*), a situação se inverte e o Bun se mostra mais rápido. Primeiro com `time`: Node: ``` real 0m12.736s user 0m10.322s sys 0m1.732s ``` Bun: ``` real 0m5.140s user 0m2.289s sys 0m1.335s ``` E com o Benchmark.js: Node: ``` test x 0.09 ops/sec ±0.15% (5 runs sampled) ``` Bun: ``` test x 0.21 ops/sec ±0.15% (5 runs sampled) ``` Provavelmente por causa [do que já mencionei](https://stackoverflow.com/q/6853566), de que a implementação do `console.log` no Node piora bastante a performance. No primeiro código não causa problema porque é só uma chamada no final e o grosso do trabalho é no cálculo, mas no segundo já faz diferença. --- Curiosamente, se não usar `BigInt`, aí muda de novo: ```javascript // diminuí o n para não estourar o valor máximo de Number let n = 1000; let a = 0, b = 1; for (let i = 0; i < n; i++) { [a, b] = [b, a + b]; } ``` Usando este código, o Bun foi **muito** mais rápido que o Node, tanto no Mac quanto no Linux (em média cerca de 10 vezes mais rápido).
só que usando esse codigo tu nao chega em `n` de 100.000 imagina 1.000.000 haha BigInt parece ser uma limitação do bun atual, sobre o `console.log` se nao me engano ele vai direto pra API nativa no V8, provavelmente aqui temos uma diferença do Zig no bun?
Bom, a ideia era eliminar o uso de `BigInt` pra ver se mudava alguma coisa, então o jeito foi diminuir o valor. Mas se somente o `BigInt` fosse o problema, então daria diferença no Linux também, mas aqui deu "empate técnico". Talvez seja a combinação `BigInt` + Mac que cause essa perda de desempenho, fica aí a questão pra uma futura investigação :-) Também pensei se a desestruturação faz alguma diferença, fica aí outra sugestão de teste também (usar atribuições simples em vez de `[a, b] = [b, a + b]`).
Bom, fiz o teste comparando os algoritmos com e sem desestruturação, e também com e sem `BigInt`: ```javascript var Benchmark = require('benchmark'); var suite = new Benchmark.Suite; suite .add('desestruturação', function () { const n = 1000; let a = 0, b = 1; for (let i = 0; i < n; i++) { [a, b] = [b, a + b]; } }) .add('sem desestruturação', function () { const n = 1000; let a = 0, b = 1; for (let i = 0; i < n; i++) { let tmp = a; a = b; b += tmp; } }) .add('desestruturação BigInt', function () { const n = 1000000n; let a = 0n, b = 1n; for (let i = 0n; i < n; i++) { [a, b] = [b, a + b]; } }) .add('sem desestruturação BigInt', function () { const n = 1000000n; let a = 0n, b = 1n; for (let i = 0n; i < n; i++) { let tmp = a; a = b; b += tmp; } }) .on('complete', function () { console.log('Fastest is ' + this.filter('fastest').map('name')); }) .on('cycle', function (event) { console.log(String(event.target)); }) .run({ 'async': true }); ``` Testei só no Linux, porque no Mac já vimos que `BigInt` fica bem mais lento usando o Bun. Resultados (em operações por segundo, ou seja, **quanto mais, melhor**): | Teste | Node | Bun | |------------------------------|-----------|-----------| | desestruturação | 236.387 | 3.920.325 | | sem desestruturação | 1.085.075 | 3.897.458 | | desestruturação `BigInt` | 0,11 | 0,11 | | sem desestruturação `BigInt` | 0,12 | 0,11 | Ou seja, parece que a implementação da desestruturação no Bun é mais rápida que no Node. Basta ver que sem desestruturação e sem `BigInt`, o Node pulou de 236 mil para 1 milhão de operações por segundo (e mesmo assim não chegou perto do Bun). Mas quando `BigInt` é usado, a diferença já não foi tão grande. Imagino que neste caso o *overhead* dos cálculos parece ter um impacto maior que a desestruturação.
Vou compartilhar o resultado do benchmark com o M1 Pro: ``` ~/projects/bun-benchmark  node index.js test x 0.17 ops/sec ±2.08% (5 runs sampled) ~/projects/bun-benchmark  bun index.js test x 0.07 ops/sec ±1.74% (5 runs sampled) ``` Executei o teste algumas vezes, e em todas elas, o node foi em média 2x mais rápido. De fato, parece que o node é mais rápido no M1/M1 Pro (e ainda melhor no M1 Max), porém mais lento (ou praticamente igual) no Intel.
isso é muito louco porque é o oposto que eu imaginaria, pelo fato do bun usar runtime com engine do "safari"
> Eu vou postar um video amanhã sobre e vou colocar o link do TabNews nele Opa, que bom que avisou sobre o vídeo dessa vez! hahaha Pra aguentar o volume de acessos vindos pelo seu vídeo, já vou trocar aqui o Node pelo Bun no TabNews... 😜 Não, péra! Vendo os comparativos, é melhor adicionar uns pentes de memória e trocar o HD por SSD pra dar um gás no servidor 🤣🚀 Falando sério agora... É muito massa que sempre vem um pico de acessos e de novos cadastros quando você fala do TabNews nos seus vídeos. 💪🚀

Fiz alguns testes também sem bibliotecas em uma máquina linux com fedora 38 (dell Intel® Core™ i5-8350U × 8)

1. Teste de Operações com BigInt (Números de Fibonacci):

console.time("Execution Time");
const n = 1000000;
let a = BigInt(0), b = BigInt(1);
for (let i = BigInt(0); i < n; i++) {
  [a, b] = [b, a + b];
}
console.timeEnd("Execution Time");

Resultados: Node.js: 13.770s Bun: 32.01s

2. Teste de Operações de I/O:

console.time("Execution Time");
const n = 1000000;
for (let i = BigInt(0); i < n; i++) {
    console.log("Item: " + i);
}
console.timeEnd("Execution Time");

Resultados:

Node.js: 17.787s Bun: 5.27s

3. Teste de Alocação de Memória:

console.time("Memory Allocation Execution Time");
const n = 1000;
for (let i = 0; i < n; i++) {
    let arr = new Array(100000).fill(0);
}
console.timeEnd("Memory Allocation Execution Time");

Resultados:

Node.js: 2.162s Bun: 1.78s

4. Teste de Manipulação de Strings:

console.time("String Manipulation Execution Time");
let result = "";
const baseString = "abcdefghijklmnopqrstuvwxyz";
const n = 100000;
for (let i = 0; i < n; i++) {
    result += baseString;
}
console.timeEnd("String Manipulation Execution Time");

Resultados:

Node.js: 9.487ms Bun: 4.12ms

5. Teste de Manipulação de Arrays:

console.time("Array Operations Execution Time");
const n = 100000;
let arr = [];
for (let i = 0; i < n; i++) {
    arr.push(i);
}
for (let i = 0; i < n; i++) {
    let item = arr[i];
}
for (let i = 0; i < n; i++) {
    arr.pop();
}
console.timeEnd("Array Operations Execution Time");

Resultados:

Node.js: Média de 8.347ms Bun: Média de 7.91ms

6. Teste de Operações Matemáticas Básicas:

console.time("Basic Math Operations Execution Time");
let result = 0;
const n = 1000000;
for (let i = 1; i <= n; i++) {
    result += i;
    result -= i;
    result *= i;
    result /= i;
}
console.timeEnd("Basic Math Operations Execution Time");

Resultados:

Node.js: Média de 11.115ms Bun: Média de 15.423ms

Parece que o bun se destaca em operações de I/O, agora o Node.js tem uma vantagem em operações aritméticas, especialmente com BigInt

Só de curiosidade, refiz esses testes usando o [Benchmark.js](). Só adicionei mais um caso, de Fibonacci sem `BigInt`, pois vi que deu diferença. Segue o código: ```javascript var Benchmark = require('benchmark'); var suite = new Benchmark.Suite; suite .add('Fibonacci BigInt', function () { const n = 1000000n; let a = BigInt(0), b = BigInt(1); for (let i = BigInt(0); i < n; i++) { [a, b] = [b, a + b]; } }) .add('Fibonacci sem BigInt', function () { // tive que diminuir n para não estourar o valor máximo de Number const n = 1000; let a = 0, b = 1; for (let i = 0; i < n; i++) { [a, b] = [b, a + b]; } }) .add('console.log no loop', function () { const n = 1000000; for (let i = BigInt(0); i < n; i++) { console.log("Item: " + i); } }) .add('Alocação de memória', function () { const n = 1000; for (let i = 0; i < n; i++) { let arr = new Array(100000).fill(0); } }) .add('Manipulação de strings', function () { let result = ""; const baseString = "abcdefghijklmnopqrstuvwxyz"; const n = 100000; for (let i = 0; i < n; i++) { result += baseString; } }) .add('Manipulação de arrays', function () { const n = 100000; let arr = []; for (let i = 0; i < n; i++) { arr.push(i); } for (let i = 0; i < n; i++) { let item = arr[i]; } for (let i = 0; i < n; i++) { arr.pop(); } }) .add('Operações matemáticas', function () { let result = 0; const n = 1000000; for (let i = 1; i <= n; i++) { result += i; result -= i; result *= i; result /= i; } }) .on('cycle', function (event) { console.log(String(event.target)); }) .run({ 'async': true }); ``` Os resultados estão abaixo (os valores são de operações por segundo, ou seja, **quanto mais, melhor**). Linux (Ubuntu 22.04.3, processador 11th Gen Intel® Core™ i5-1145G7 2.60GHz, 8 núcleos): | Teste | Node | Bun | |:-----------------------|:-------|:---------------------------------| | Fibonacci BigInt | 0,07 | 0,07 | | Fibonacci sem BigInt | 224154 | 3507428 (sim, mais de 3 milhões) | | console.log no loop | 0,14 | 0,31 | | Alocação de memória | 2,51 | 2,54 | | Manipulação de strings | 2260 | 1024 | | Manipulação de arrays | 649 | 1882 | | Operações matemáticas | 198 | 222 | Mac (2012, processador 2.6 GHz Quad-Core Intel Core i7): | Teste | Node | Bun | |:-----------------------|:-------|:--------| | Fibonacci BigInt | 0,12 | 0,03 | | Fibonacci sem BigInt | 136482 | 1547414 | | console.log no loop | 0,08 | 0,18 | | Alocação de memória | 1,49 | 2,7 | | Manipulação de strings | 1483 | 1033 | | Manipulação de arrays | 453 | 1374 | | Operações matemáticas | 122 | 118 | Ou seja, o Node em geral se sai pior no `console.log` dentro de um loop (pelos motivos já citados em vários comentários). O cálculo com `BigInt` faz muita diferença no Mac (o Bun se sai pior), mas no Linux dá empate técnico. Em compensação, sem `BigInt` o Bun ganha por uma diferença enorme. E nas outras operações ora um, ora outro se sai melhor, com variados graus de vantagem.
wow! muito massa quebrar em 6 tipos de op. ficou muito bom ver a diferença! **IMPORTANTE:** `console.log` nem sempre vai ser I/O, no NodeJS de fato ele vai virar um `process.stdout.write()` e olhando pro [codigo fonte](https://github.com/oven-sh/bun/blob/d26addeca147e076d7a5e2c7fe14febdd658393f/src/bun.js/bindings/exports.zig#L2843) do bun: > but it's important that console.log() is fast. No bun o `console.log` vai virar um **synchronous printf** vs. no NodeJS que se vai ser um asynchronous com stdout

Depende de que forma mais rapido, o problema do node não é só em velocidade de execução, o tooling é uma merda, transpilar e configurar um projeto ts é chato. Com bun tu tem praticamente tudo isso out of the box. Sendo que o tooling é inclusive mais rapido que o pnpm. E a loucura de esmodule e common js, tudo isso é horrível no node.

Executei uma série de benchmarks na minha máquina com as seguintes especificações:

  • WSL 2 Ubuntu 22.04.2 LTS
  • AMD Ryzen 7 5700x 4.6Ghz, 8 núcleos
  • RAM 16gb 3200Mhz CL18

Utilizei uma suíte de testes fornecida pelo @kht, que incluiu os seguintes casos de teste:

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;

suite
.add('desestruturação', function () {
    const n = 1000;
    let a = 0, b = 1;
    for (let i = 0; i < n; i++) {
      [a, b] = [b, a + b];
    }
})
.add('sem desestruturação', function () {
    const n = 1000;
    let a = 0, b = 1;
    for (let i = 0; i < n; i++) {
        let tmp = a;
        a = b;
        b += tmp;
    }
})
.add('desestruturação BigInt', function () {
    const n = 1000000n;
    let a = 0n, b = 1n;
    for (let i = 0n; i < n; i++) {
      [a, b] = [b, a + b];
    }
})
.add('sem desestruturação BigInt', function () {
    const n = 1000000n;
    let a = 0n, b = 1n;
    for (let i = 0n; i < n; i++) {
        let tmp = a;
        a = b;
        b += tmp;
    }
})
.on('complete', function () {
    console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.on('cycle', function (event) {
    console.log(String(event.target));
})
.run({
    'async': true
});

Os resultados obtidos foram os seguintes:

Teste Node Bun
desestruturação 1.350.540 884.238
sem desestruturação 1.392.095 1.662.632
desestruturação BigInt 0.16 0.10
sem desestruturação BigInt 0.16 0.10

Só queria agregar aqui tenho um notebook que está usando o POP_OS 22.04 e rodei o bun com o zsh. esse mesmo Fibonacci demorou em média 14s enquanto o node demorou 12s.

tenho um i7 de 8ª geração. Durante a execução estava com o Google Chrome, Egde, VS Code aberto.

Alo pessoal. A galera ja comentou sobre diversos fatores que podem influenciar aqui... so queria compartilhar os resultados de uma maquina mais "humilde" (que nao é humilde pq no fim eh um mac mas vcs entenderam...)

Configuracao

MacBook Air 2020 1,6 GHz Dual-Core Intel Core i5, no macOS Ventura 13.4 (22F66) Node --v 18.17.1 Bun -version 1.0.2

Teste

console.time("execution time")

function fib(n) {
  let a = BigInt(0), b = BigInt(1);
  for (let i = BigInt(0); i < n; i++) {
    [a, b] = [b, a + b]
    console.log("a:", a, "b:",b)
  }
  return a.toString()
}

for(let i = 100; i > 0; i--){
  let result = fib(10000)
  console.log(result)
}

console.timeEnd("execution time")

Resultado

Runtime Tempo total(m:ss.mmm) Média(ss.mmm)
Node 7:06.114 04.261
Bun 9:42.06 05.821

Ao que parece ser realmente é a forma como a compilação do bun em arm64 está funcionando, tem alguns issues acerca da arquitetura, erros que não ocorrem na compilação realizada para amd/intel. Pode ser que seja alguma implementação para arm64 que faz com que seja mais rápido.

Um dos principais core do projeto (Jarred-Sumner), fez a seguinte fala: If you run into performance issues with real code in your application feel free to file an issue

This looks more like a microbenchmark. JS engines are really good at optimizing microbenchmarks with statically known data. It probably isn't meaningful in applications.

logo:

Se você tiver problemas de desempenho com código real em seu aplicativo, sinta-se à vontade para registrar um problema

Isso se parece mais com um microbenchmark. Os mecanismos JS são realmente bons para otimizar microbenchmarks com dados estaticamente conhecidos. Provavelmente não é significativo em aplicativos.

https://github.com/oven-sh/bun/issues/3358

Sobre o código:

`var appendDelay = 1; var chartLen = 10; var delaysSoFar = 0; var arr = [0];

function update(x) { if (arr.length < chartLen) { if (delaysSoFar == appendDelay) { arr.push(x); delaysSoFar = 0; } else { arr[arr.length - 1] = x; } delaysSoFar += 1; }

if (arr.length == chartLen) { for (var i = 0; i < 10; i += 2) { arr[i / 2] = arr[i]; } arr.length = 5;

appendDelay *= 2; arr.push(x); } }

const now = performance.now(); for (var i = 0; i < 1000000000; i++) { update(i); } console.log(performance.now() - now);

console.log(arr);`

obs. ~~ Outro detalhe que eu acredito fazer parte do processo é que mesmo o webpack sendo apple, ela roda em outras máquinas que utilizam o webkit como o gnome epiphany (browser do gnome uma DE linux). Então não acredito que seja isso que possa fazer alguma diferença. ~~ E um ultimo detalhe é Lucas sempre vejo seus videos, bom trabalho.

Que balde de água fria, hein. Está o maior hype que o bun é mais rápido porque foi feito em Rust. Um monte de gente repetindo que bun é mais rápido, porém a realidade é que praticamente estão empatados. Supostamente pelo menos bun é mais seguro, mas não duvido alguém fazer testes reais e descobrir falhas. Nota: Estou repetindo feito papagaio que o Rust é seguro, por ouvir que ele é seguro, mas não manjo de segurança e claramente nunca testei a segurança de Rust.

Mas o Bun é escrito em Zig, não tem nada de Rust no código dele, [veja](https://github.com/oven-sh/bun). Quem foi feito em Rust é o [Deno](https://github.com/denoland/deno). De qualquer forma, pelos testes básicos que fiz, e por vários benchmarks que vi por aí, em alguns casos o Bun foi mais rápido sim. Mas sempre tem quem compra o marketing cegamente e entende "*então é sempre mais rápido*". Não é. Até onde vi, depende do caso, tem vezes que é melhor, em outras é pior e em outras tanto faz. Como eu disse no [outro comentário](/kht/132ba7e8-eee5-44eb-90b9-c4fe78316332), o ideal é que cada um testasse para ver se no seu caso específico faz diferença, e então decidir se vale a pena. Infelizmente, parece que muitas pessoas preferem acreditar na solução mágica que sempre vai ser melhor pra tudo. E pra essas, qualquer coisa será um balde de água fria, pois tal solução não existe.
Então piorou, há mais mentiras ainda, eu sempre ouvi falar que usaram Rust.
Sempre ouviu de quem? Na [documentação oficial](https://bun.sh/docs), logo no segundo parágrafo, tá bem claro que foi escrito em Zig. Se alguém mentiu, não foram os criadores do Bun, provavelmente foi alguém que sequer leu a documentação... ¯\\\_(ツ)\_/¯
Está pasando verganha dizendo algo que você claramente não sabe, está apenas repetendo igual um papagaio o que ouviu por ai, se eu fosse você já teria apagado esse post correndo!