Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are my prototypes so slow?

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?

like image 478
vrugtehagel Avatar asked Feb 06 '23 04:02

vrugtehagel


1 Answers

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.

Strict mode

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 specified this is not boxed into an object.

You'll find the added performance cost will evaporate when switching to strict mode with:

"use strict";
like image 100
trincot Avatar answered Feb 07 '23 17:02

trincot