node.js - 使用 Node ,为什么使用 "use strict"的代码要快得多?

标签 node.js optimization v8 strict

我从来不知道 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”,结果与this内联,

$ 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 .有趣的是,bluebird 优化指南并没有提到 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 我仍然看到同样的事情。使用严格的情况在未优化的代码上速度较慢,在优化的代码上速度更快,

不严格

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)

"使用严格;"

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)

最佳答案

这种缓慢的原因在于 this check在 ArraySlice 内置。它测试我们是否尝试对参数对象进行切片,如果这样做,则使用快速代码来执行此操作。但是它只检查 sloppy mode 参数对象。当您在严格函数中分配参数对象时,您会得到由 native_context()->strict_arguments_boilerplate() 制成的 strict mode 参数对象,这意味着上面的检查无法识别它并失败到通用的 JavaScript 代码,它比专门的手工编码 C++ 快速路径慢,它会为一个草率的参数对象。

关于node.js - 使用 Node ,为什么使用 "use strict"的代码要快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23997267/

相关文章:

node.js - sails.js - 获取空白页

algorithm - 图轴的刻度线算法

c++ - 如何从 C++ 调用 javascript 回调

android - 如何为 Android NDK 中的特定文件设置优化级别?

python - 迭代字符串列表中字符的最快对象

v8 - 为什么我的 V8 构建在 AWS 上的 Ubuntu 上失败,并显示有关谷歌存储文件不存在的消息?

javascript - 在 V8 中,如何在垃圾回收 JavaScript 对象后删除包装的 C++ 对象?

javascript - Meteor/Node.js : Multiple http requests within a for loop, 在时间间隔内均匀分布?

node.js - Nodejs 模板 yaml 文件

Node.js 使用用户名和密码从 URL 下载文件?