closure vs compund

JavaScript performance comparison

Revision 2 of this test case created by Timo

Preparation code

 
<script>
Benchmark.prototype.setup = function() {
    var Edge = function() {
      this.a = 0;
      this.nextEdge = null;
      // +20 other members
    }
    function ProcessEdge(e)
    {
      // some processing and then
      e.Value = e.Value.nextEdge; // instead of e = e.nextEdge;
      return e.Value.a-10;
    }
   
    function ProcessEdge2(e)
    {
      // some processing and then
      e = e.nextEdge; // instead of e = e.nextEdge;
      return {Value: e, Res: e.a-10};
    }
    var global_ret = 0;
    function ProcessEdge3(e)
    {
      // some processing and then
      e = e.nextEdge; // instead of e = e.nextEdge;
      global_ret = e.a-10;
      return e;
    }
    var global_val = {};
    function ProcessEdge4(e)
    {
      // some processing and then
      e = e.nextEdge; // instead of e = e.nextEdge;
      global_ret = e.a-10;
      global_val = e;
    }
    var global_val6 = function(){this.Value=new Edge();};
    function ProcessEdge6(e)
    {
      // some processing and then
      e = e.nextEdge; // instead of e = e.nextEdge;
      global_ret = e.a-10;
      global_val6.Value = e;
    }
   
    function main(a)
    {
      // And the calling part:
    var res=0, res2, e, b;
    for (var i=0;i<10000;i++)
    {
      e = new Edge();
      b = new Edge();
      b.a = i*a;
   
      e.nextEdge = b;
     
      // some processing and then
      res += (function ()
      {
        e = { Value: e };
        res2 = ProcessEdge(e);
        e = e.Value;
        return res2;
      })
      .call(this);
      if (e!=b) res+=1000;
    }
      return res;
    }
    function main2(a)
    {
      var res=0, res2, e, b;
      for (var i=0;i<10000;i++)
      {
   
      // And the calling part:
      e = new Edge();
      b = new Edge();
      b.a = i*a;
      e.nextEdge = b;
     
      // some processing and then
      res2 = ProcessEdge2(e);
      e = res2.Value;
      res += res2.Res;
      if (e!=b) res+=1000;  
     }  
     return res;
    }
   
    function main3(a)
    {
      var res=0, res2, e, b;
      for (var i=0;i<10000;i++)
      {
   
      // And the calling part:
      e = new Edge();
      b = new Edge();
      b.a = i*a;
      e.nextEdge = b;
     
      // some processing and then
      e = ProcessEdge3(e);
      res += global_ret;
      if (e!=b) res+=1000;  
     }  
     return res;
    }
   
    function main4(a)
    {
      var res=0, res2, e, b;
      for (var i=0;i<10000;i++)
      {
   
      // And the calling part:
      e = new Edge();
      b = new Edge();
      b.a = i*a;
      e.nextEdge = b;
     
      // some processing and then
      ProcessEdge4(e);
      e = global_val;
      res += global_ret;
      if (e!=b) res+=1000;
     }  
     return res;
    }
   
    function main5(a)
    {
      // And the calling part:
      var res=0, res2, e, b, d={};
    for (var i=0;i<10000;i++)
    {
      e = new Edge();
      b = new Edge();
      b.a = i*a;
   
      e.nextEdge = b;
     
      // some processing and then
      res += (function ()
      {
        d.Value = e;
        res2 = ProcessEdge(d);
        e = d.Value;
        return res2;
      })();
      if (e!=b) res+=1000;
    }
      return res;
    }
   
    function main6(a)
    {
      var res=0, res2, e, b;
      for (var i=0;i<10000;i++)
      {
   
      // And the calling part:
      e = new Edge();
      b = new Edge();
      b.a = i*a;
      e.nextEdge = b;
     
      // some processing and then
      ProcessEdge6(e);
      e = global_val6.Value;
      res += global_ret;
      if (e!=b) res+=1000;
     }  
     return res;
    }
   
    function main7(a)
    {
      // And the calling part:
    var res=0, res2, e, b;
    for (var i=0;i<10000;i++)
    {
      e = new Edge();
      b = new Edge();
      b.a = i*a;
   
      e.nextEdge = b;
     
      // some processing and then
      res += _ProcessEdge();
      if (e!=b) res+=1000;
    }
      return res;
   
      function _ProcessEdge()
      {
        // some processing and then
        e = e.nextEdge;
        return e.a-10;
      }
   
    }
   
    function main8(a)
    {
      var pseudo_global_ret = 0;
   
    var res=0, res2, e, b;
    for (var i=0;i<10000;i++)
    {
      e = new Edge();
      b = new Edge();
      b.a = i*a;
   
      e.nextEdge = b;
     
      // some processing and then
      _ProcessEdge();
      res += pseudo_global_ret;
      if (e!=b) res+=1000;
    }
      return res;
   
      function _ProcessEdge()
      {
        // some processing and then
        e = e.nextEdge;
        pseudo_global_ret = e.a-10; // instead of return e.a-10
      }
    }
   
    function main9(a)
    {
    var res=0, res2, e, b;
    for (var i=0;i<10000;i++)
    {
      e = new Edge();
      b = new Edge();
      b.a = i*a;
   
      e.nextEdge = b;
     
      // some processing and then
      _ProcessEdge();
      res += global_ret;
      if (e!=b) res+=1000;
    }
      return res;
   
      function _ProcessEdge()
      {
        // some processing and then
        e = e.nextEdge;
        global_ret = e.a-10; // instead of return e.a-10
      }
    }
   
    function main10(a)
    {
    var res=0, res2, e, b;
    for (var i=0;i<10000;i++)
    {
      e = new Edge();
      b = new Edge();
      b.a = i*a;
   
      e.nextEdge = b;
     
      // now the same without any functions
      e = e.nextEdge;
      res += e.a-10;
   
      if (e!=b) res+=1000;
    }
      return res;
   
    }
   
    function ProcessEdge11(e)
    {
      e = e.nextEdge;
      global_val = e;
      return e.a-10;
    }
   
    function main11(a)
    {
      var res=0, res2, e, b;
      for (var i=0;i<10000;i++)
      {
   
      // And the calling part:
      e = new Edge();
      b = new Edge();
      b.a = i*a;
      e.nextEdge = b;
     
      // some processing and then
      res += ProcessEdge11(e);
      e = global_val;
      if (e!=b) res+=1000;  
     }  
     return res;
    }
   
    var a,b,c;
};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Closure
a = main(10);
b = main(20);
c = main(30);
 
pending…
Compound
a = main2(10);
b = main2(20);
c = main2(30);
pending…
Using global return value
a = main3(10);
b = main3(20);
c = main3(30);
pending…
Using global ret & val
a = main4(10);
b = main4(20);
c = main4(30);
pending…
Closure variant
a = main5(10);
b = main5(20);
c = main5(30);
pending…
Using global ret & val 2
a = main6(10);
b = main6(20);
c = main6(30);
pending…
Function inside function
a = main7(10);
b = main7(20);
c = main7(30);
pending…
Function inside function 2
a = main8(10);
b = main8(20);
c = main8(30);
pending…
Function inside function 3
a = main9(10);
b = main9(20);
c = main9(30);
pending…
Full inline
a = main10(10);
b = main10(20);
c = main10(30);
pending…
Using global val
a = main11(10);
b = main11(20);
c = main11(30);
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

0 comments

Add a comment