Tenho o seguinte script comparando o tempo que leva para declarar um objeto com uma classe em comparação diretamente com um objeto.
console.time("class decls");
class Dog {
a;
constructor() {
this.a = 1;
}
bark() {
this.a + this.a;
}
}
for (let i = 0; i < 1_000_000; ++i) {
let dog = new Dog();
dog.bark();
}
console.timeEnd("class decls");
console.time("object decls");
for (let i = 0; i < 1_000_000; ++i) {
let dog = {
a: undefined,
bark() {
this.a + this.a;
}
}
{ // inlining the constructor
dog.a = 1;
}
dog.bark();
}
console.timeEnd("object decls");
Os resultados parecem favorecer fortemente o primeiro método, apresentando os seguintes tempos quando executado com Bun e resultados semelhantes quando executado com Node:
[8.46ms] class decls
[27.98ms] object decls
Por que é muito mais rápido declarar uma classe e então construir um novo objeto dela? Há algum cache acontecendo ou é outra coisa?
Como @trincot mencionou no comentário acima, o comportamento que você vê tem a ver com a forma como os mecanismos JavaScript (V8, JavaScriptCore e SpiderMonkey) otimizam objetos e alocações de funções internamente.
Os métodos das classes são colocados no protótipo
O que significa que quando você escreve
O
bark
método “vive” emDog.prototype
, portanto ele é criado apenas uma vez.Cada nova
Dog
instância se referirá à mesmabark
funçãoOs objetos criam uma função cada vez que são alocados
Quando você escreve
No seu código, a cada iteração, uma nova
bark
função é alocada.Em termos de alocação, é claro que essa abordagem é mais cara, porque o JIT não pode reutilizar a mesma função em todos os objetos.
Espero que isso ajude.
Você não está fazendo a mesma coisa.
Ao declarar uma classe, você declara as funções uma vez. Elas usam exatamente a mesma memória, independentemente de você criar 1 ou 100 milhões de objetos.
Ao declará-lo como um objeto literal, você cria uma função completamente nova para cada objeto. Ele ocupa mais memória.
Você esqueceu da terceira opção, como ela era resolvida antes de
class
ser introduzida: a declaração do protótipo.Quando testei as diferentes soluções, obtive tempos muito variados, mas a solução protótipo parece ser mais rápida na maioria das vezes no Chrome.