I have the following script benchmarking the time it takes to declare an object with a class vs. directly with an object.
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");
The results seem to heavily favor the first method, giving the following times when run with Bun and similar results when run with Node:
[8.46ms] class decls
[27.98ms] object decls
Why is it so much faster to declare a class and then construct a new object thereof? Is there some caching going on, or is it something else?
2
Answers
In JavaScript, class declarations represent a modern structure and are an optimized feature in terms of performance. Object declarations, on the other hand, are an older and more general structure.
As @trincot mentioned in the comment above, the behavior you see has to do with how JavaScript engines (V8, Bun, Deno …) optimize objects and function allocations under the hood.
Classes’ methods are put on the prototype
Meaning that when you write
The
bark
method “lives” onDog.prototype
, therefore it is created only once.Every new
Dog
instance will refer to the samebark
functionObject create a function each time they get allocated
When you write
In your code, on every iteration a new
bark
function gets allocated.In terms of allocation of course this approach is more expensive, because the JIT can’t reuse the same function across all objects.
Hope this helps.