Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using node, why is code so much faster with "use strict"?

I never knew use strict to speed up runtime, however a simple use strict is making my benchmark substantially faster, and the slower one grossly slower (over twice as slow). What's going on?

//
// 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();

Without that top "use strict", the results are inline with 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

However, with that "use strict;", I'm getting this,

$ 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

I'm running nodejs v0.11.13. This is all part of the work I'm doing to speed up node-thunkify using this guide. Interestingly the bluebird optimization guide does not mention use strict;'s beneficial performance.

Messing around with it more, if I change the test case to be,

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();

thereby removing the calls thunkify I still see the same thing.. The case with use strict is slower on unoptimized code, and faster on optimized code,

No 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)

"use strict;"

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)
like image 834
NO WAR WITH RUSSIA Avatar asked Jun 02 '14 14:06

NO WAR WITH RUSSIA


People also ask

Is strict mode faster?

Strict mode eliminates some JavaScript silent errors by changing them to throw errors. Strict mode fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that's not strict mode.

Why We Use Use strict in NodeJS?

The purpose of "use strict" is to indicate that the code should be executed in "strict mode". With strict mode, you can not, for example, use undeclared variables. The numbers in the table specify the first browser version that fully supports the directive. You can use strict mode in all your programs.

Why is NodeJS code fast?

js is so fast. Node. js is single-threaded and asynchronous: this means that all I/O activity does not interfere with other processes, and it is possible to send emails, read and write files, query databases, and so on, all at the same time. Each request to the web server does not have a different Node.

What is the benefit of using use strict `?

Benefits of using “use strict” It changes previously accepted "bad syntax" into real errors. As an example, mistyping a variable name creates a new global variable. When using strict mode, this will throw an error. It leads to making it impossible to accidentally create a global variable.


2 Answers

The reason for this slowness is in this check inside ArraySlice builtin. It tests whether we are trying to slice arguments object and if we do, then uses a fast code to do that. However it only checks for sloppy mode arguments object. When you allocate arguments object inside the strict function you get strict mode arguments object made from native_context()->strict_arguments_boilerplate() which means the check above fails to recognize it and falls through to the generic JavaScript code which is slower than specialized hand-coded C++ fast path it would take for a sloppy arguments object.

like image 120
Vyacheslav Egorov Avatar answered Oct 02 '22 16:10

Vyacheslav Egorov


Following is a quote from Mozilla's article on JavaScript Strict Mode

JavaScript's flexibility makes it effectively impossible to do this without many runtime checks. Certain language functions are so pervasive that performing runtime checks has considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks.

The above quote makes it quite clear that there are certain performance improvements while using strict mode.

As you know, strict mode disables several features which JavaScript provided previously(most of them considered bad practice). Since the browser can easily throw errors when using strict mode, it doesn't have to perform checks and assume code corrections for you. Thus, leading to performance improvements.

like image 31
Chetan Bhasin Avatar answered Oct 02 '22 15:10

Chetan Bhasin