我从来不知道use strict
可以加快运行时间,但是一个简单的use strict
使我的基准测试速度更快,而速度更慢的速度更慢(速度超过两倍)。发生了什么事?
//
// RUN WITH AND WITHOUT THIS
//
"use strict";
var assert = require('assert');
var slice = [].slice;
function thunkify_fast(fn){
assert('function' == typeof fn, 'function required');
return function(){
var args = new Array(arguments.length);
for(var i = 0; i < args.length; ++i) {
args[i] = arguments[i];
}
var ctx = this;
return function(done){
var called;
args.push(function(){
if (called) return;
called = true;
done.apply(null, arguments);
});
try {
fn.apply(ctx, args);
} catch (err) {
done(err);
}
}
}
};
function thunkify_slow(fn){
assert('function' == typeof fn, 'function required');
return function(){
var args = slice.call(arguments);
var ctx = this;
return function(done){
var called;
args.push(function(){
if (called) return;
called = true;
done.apply(null, arguments);
});
try {
fn.apply(ctx, args);
} catch (err) {
done(err);
}
}
}
};
var fn = function () { };
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;
//
// Only one wrapper can be sent through the optimized compiler
//
suite.add( 'thunkify#fast', function () { thunkify_fast(fn)(function(){}) } )
.add( 'thunkify#slow', function () { thunkify_slow(fn)(function(){}) } )
.on('cycle', function(event) { console.log(String(event.target)); })
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
.run();
如果没有顶部"use strict"
,则结果与此内联,
$ node --allow-natives-syntax test.js
thunkify#fast x 8,511,605 ops/sec ±1.22% (95 runs sampled)
thunkify#slow x 4,579,633 ops/sec ±0.68% (96 runs sampled)
Fastest is thunkify#fast
然而,凭借"use strict;"
,我得到了这个,
$ node --allow-natives-syntax test.js
thunkify#fast x 9,372,375 ops/sec ±0.45% (100 runs sampled)
thunkify#slow x 1,483,664 ops/sec ±0.93% (96 runs sampled)
Fastest is thunkify#fast
我正在运行nodejs v0.11.13。这是我使用speed up node-thunkify对this guide所做工作的全部内容。有趣的是,蓝鸟优化指南未提及use strict;
的有益表现。
如果我将测试用例更改为
,请更多地了解它var f_fast = thunkify_fast(fn);
var f_slow = thunkify_slow(fn);
suite.add( 'thunkify#fast', function () { f_fast(function(){}) } )
.add( 'thunkify#slow', function () { f_slow(function(){}) } )
.on('cycle', function(event) { console.log(String(event.target)); })
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
.run();
从而删除了调用thunkify
我仍然看到相同的事情..使用strict的情况在未经优化的代码上较慢,在优化代码上更快,
没有严格
thunkify#fast x 18,910,556 ops/sec ±0.61% (100 runs sampled)
thunkify#slow x 5,148,036 ops/sec ±0.40% (100 runs sampled)
&#34;使用严格;&#34;
thunkify#fast x 19,485,652 ops/sec ±1.27% (99 runs sampled)
thunkify#slow x 1,608,235 ops/sec ±3.37% (93 runs sampled)
答案 0 :(得分:14)
这种缓慢的原因在于ArraySlice内置的this check。它测试我们是否尝试切片参数对象,如果我们这样做,那么使用快速代码来做。但是它只检查 sloppy mode arguments对象。当您在strict函数内部分配参数对象时,您将获得由native_context()->strict_arguments_boilerplate()
生成的 strict mode 参数对象,这意味着上面的检查无法识别它,并且会落入通用JavaScript代码,该代码比一个专门的手工编码的C ++快速路径,它需要一个草率的参数对象。
答案 1 :(得分:11)
以下是Mozilla's article on JavaScript Strict Mode
的引用JavaScript的灵活性使得实际上无法做到这一点 没有很多运行时检查。某些语言功能是如此 普遍认为执行运行时检查具有相当大的性能 成本。一些严格的模式调整,加上要求用户提交 JavaScript是严格的模式代码,并且可以在某种情况下调用 方式,大大减少了那些运行时检查的需要。
以上引用清楚地表明在使用严格模式时会有一些性能提升。
如您所知,严格模式会禁用JavaScript之前提供的几个功能(大多数功能被认为是不好的做法)。由于浏览器在使用严格模式时很容易抛出错误,因此不必执行检查并为您进行代码更正。因此,导致性能提升。
答案 2 :(得分:9)
只想补充Chetan的答案。我会指出你刚才问过的question。很可能这有答案。
严格模式对您的代码做出某些假设并添加额外的检查。这些检查有两个与性能相关的效果(与普通模式相比):
只要2超过1,性能将在严格模式下得到改善。这对您的第一个功能起到了预期的作用。对于您的第二个功能,无法进行优化!当编译器看到不安全的参数使用时,编译器会退出。所以剩下的就是第一个效果。
我认为不可优化的代码在严格的代码中会受到更多的惩罚。额外的检查没有任何结果。