Reputation: 261
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
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:
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:
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
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