为什么我的原型这么慢?

vru*_*gel 4 javascript benchmarking prototype

好的,所以我写了这个简单的javascript函数,使我的代码更具可读性:

Number.prototype.isBetween=function(a,b){
    return(this>=a&&this<b);
};
Run Code Online (Sandbox Code Playgroud)

现在结果非常慢:我尝试了这个"基准"(我真的不知道如何正确地做这些事情,但这证明了我的观点):

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);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

并且第一个脚本需要大约3000毫秒的chrome(并且chrome是我正在使用的和我感兴趣的东西),而第二个脚本只需要24ms - 整个因子125 更快.是扩展现有的类javascript提供了一个非常糟糕的主意?这里发生了什么?

tri*_*cot 8

原因在于,对于isBetween要应用的方法,需要将主题k转换为Number对象.这称为拳击原始包装.

然后应用该isBetween方法,其中比较运算符>将需要从this对象中检索原始值,...两次.

这是附加函数调用(涉及堆栈)之上的所有额外开销.

总开销比需要发生的实际比较更多,因此性能影响相对较大.

严格的模式

正如@Bergi在下面的评论中提到的,上述包装不会在严格模式MDN中发生:

this严格模式下传递给函数的值不会被强制成为对象(也称为"盒装").[...]自动装箱[是]性能成本[...]因此对于严格模式函数,指定this的不会被装入对象.

当您切换到严格模式时,您会发现增加的性能成本会消失:

"use strict";
Run Code Online (Sandbox Code Playgroud)