A Moore
A Moore

Reputation: 261

Large performance variance with Javascript object instantiation size & methods

I have noticed a significant performance difference among the various object instantiation methods. Furthermore, it seems as though the size of the object (i.e. # of properties) matters greatly sometimes.

Can anyone shed some light on the results of the following jsperf? http://jsperf.com/objects-w-more-less-8-properties/5

var thisobj = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8} 

This seems to be hands down the fasted way to create a new object

var thisobj = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9}

This is vastly slower... the only difference being the 9th value

var thisobj = new objsm(1,2,3,4,5,6,7,8); 

AND

var thisobj = new objlg(1,2,3,4,5,6,7,8,9);

Don't differ that much from each other (about as much you would expect), but they still differ greatly from the 'dynamically' defined object above. Their objects are defined here:

    var objsm = function (a,b,c,d,e,f,g,h) {
    this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; this.f = f; this.g = g; this.h = h;}

var objlg = function (a,b,c,d,e,f,g,h,i) {
this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; this.f = f; this.g = g; this.h = h; this.i = i; }

Why is "var thisobj = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8}" so superior?

Upvotes: 4

Views: 168

Answers (2)

the8472
the8472

Reputation: 43052

Performance differences like this often are not due to the language javascript but due to the implementation of that language.

Other factors, such as heap occupancy (and thus resulting GC costs) can also affect performance.

Since there are multiple implementations out there - which are constantly evolving - and browsers don't have the habit of spitting out the generated assembly there is no general answer.

For example on FF 45 I'm getting pretty much identical performance for all four cases:

FF45 benchmark run

Presumably the JIT compilers are simply smart enough to perform dead code elimination here so we're essentially benchmarking an empty loop. In other words this result shows how well compilers optimize and not the cost of object allocations.

Making the objects escape into the global scope yields the following results, which are about what one would expect:

enter image description here

Note that a sufficiently advanced compiler™ could probably eliminate all but the last allocation from the loop by observing that they all write to the same variable without reads between iterations.

So future browser versions might "break" this benchmark again.

Microbenchmarks are tricky business.

Upvotes: 1

Little Santi
Little Santi

Reputation: 8793

My guess is that the hashmap-based form is executed natively, while the constructor-based form executes a function which needs to be interpreted. I suppose this interpretation effort causes the difference of performances.

And what about the 8-properties threshold? A HashMap needs to be pre-sized with a size over the maximum number of values it should contain (if not, accesing times will increase). If some browser vendor has chosen a low value (8-10 by example), every attempt to store more than 8 items will reduce performance.

However, the main correlation in the jsperf you mention it is not over the test, but over the browser: Every browser shows quite similar results in all tests, which is quite plausible.

Upvotes: 0

Related Questions