title: Using node, why is code so much faster with "use strict"?
body: <p>I never knew <code>use strict</code> to speed up runtime, however a simple <code>use strict</code> is making my benchmark substantially faster, and the slower one grossly slower (over twice as slow). What's going on?</p>
  
  <pre><code>//
  // 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 &lt; 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();
  </code></pre>
  
  <p>Without that top <code>"use strict"</code>, the results are inline with this,</p>
  
  <pre><code>$ 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
  </code></pre>
  
  <p>However, with that <code>"use strict;"</code>, I'm getting this,</p>
  
  <pre><code>$ 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
  </code></pre>
  
  <p>I'm running nodejs v0.11.13. This is all part of the work I'm doing to <a href="https://github.com/visionmedia/node-thunkify/pull/12" rel="noreferrer">speed up node-thunkify</a> using <a href="https://github.com/petkaantonov/bluebird/wiki/Optimization-killers" rel="noreferrer">this guide</a>. Interestingly the bluebird optimization guide does not mention <code>use strict;</code>'s beneficial performance.</p>
  
  <p>Messing around with it more, if I change the test case to be,</p>
  
  <pre><code>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();
  </code></pre>
  
  <p>thereby removing the calls <code>thunkify</code> I still see the same thing.. The case with use strict is slower on unoptimized code, and faster on optimized code,</p>
  
  <p>No strict</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>"use strict;"</p>
  
  <pre><code>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)
  </code></pre>