Okay so I wrote this simple javascript function to make my code more readable:
Number.prototype.isBetween=function(a,b){
return(this>=a&&this<b);
};
Now this turns out to be VERY slow: I tried this "benchmark" (I don't really know how to properly do this stuff but this proves my point either way):
var res=0;
var k=20;
var t=new Date().getTime();
for(var i=0;i<10000000;i++){if(k.isBetween(13,31)){res++;}}
console.log(new Date().getTime()-t);
versus
var res=0;
var k=20;
var t=new Date().getTime();
for(var i=0;i<10000000;i++){if(k>=13&&k<31)){res++;}}
console.log(new Date().getTime()-t);
and the first script takes about 3000ms in chrome (and chrome is what I'm using and what I'm interested in), whereas the second script takes only 24ms - a whole factor 125 faster. Is extending the existing classes javascript provides just a really bad idea? What is going on here?
The reason is that for the method isBetween
to be applied, the subject k needs to be converted to a Number
object. This is called boxing or primitive wrapping.
Then the isBetween
method is applied where the comparison operator >
will need to retrieve the primitive value from the this
object, ... twice.
This is all additional overhead that comes on top of the additional function call (involving the stack).
This total overhead is more work than the actual comparison that needs to happen, and so the performance impact is relatively huge.
As @Bergi mentioned in the comments below, the above-described wrapping does not happen in strict mode MDN :
the value passed as
this
to a function in strict mode is not forced into being an object (a.k.a. "boxed"). [...] automatic boxing [is] a performance cost [...] Thus for a strict mode function, the specifiedthis
is not boxed into an object.
You'll find the added performance cost will evaporate when switching to strict mode with:
"use strict";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With