Handlebars Nav Helper

JavaScript performance comparison

Revision 3 of this test case created by René

Preparation code

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script src="https://documentcloud.github.com/underscore/underscore-min.js">
</script>
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js">
</script>
<script id="bench-template-1" type="text/x-handlebars-template">
< ul >
  {{#nav1 items "in_men"}} 
    < li >{{name}} {{in_men}}< /li>
  {{/nav1}}
< /ul>
</script>
<script id="bench-template-2" type="text/x-handlebars-template">
< ul >
  {{#nav2 items "in_men"}} 
    < li >{{name}} {{in_men}}< /li>
  {{/nav2}}
< /ul>
</script>
<script id="bench-template-3" type="text/x-handlebars-template">
< ul >
  {{#nav3 items "in_men"}} 
    < li >{{name}} {{in_men}}< /li>
  {{/nav3}}
< /ul>
</script>
<script id="bench-template-4" type="text/x-handlebars-template">
< ul >
  {{#nav4 items "in_men"}} 
    < li >{{name}} {{in_men}}< /li>
  {{/nav4}}
< /ul>
</script><!-- precompiled bench-template-5 -->
<script>
(function() {
    this.JST || (this.JST = {});
    this.JST["public/templates/navigation-template"] = (function() {
        this.HandlebarsTemplates || (this.HandlebarsTemplates = {});
        this.HandlebarsTemplates["public/templates/navigation-template"] = Handlebars.template(function(Handlebars, depth0, helpers, partials, data) {
            helpers = helpers || Handlebars.helpers;
            var buffer = "",
                stack1, stack2, stack3, foundHelper, tmp1, self = this,
                functionType = "function",
                helperMissing = helpers.helperMissing,
                undef = void 0,
                escapeExpression = this.escapeExpression,
                blockHelperMissing = helpers.blockHelperMissing;

            function program1(depth0, data) {
                var buffer = "",
                    stack1;
                buffer += "\n <li>";
                foundHelper = helpers.name;
                stack1 = foundHelper || depth0.name;
                if (typeof stack1 === functionType) {
                    stack1 = stack1.call(depth0, {
                        hash: {}
                    });
                }
                else if (stack1 === undef) {
                    stack1 = helperMissing.call(depth0, "name", {
                        hash: {}
                    });
                }
                buffer += escapeExpression(stack1) + " ";
                foundHelper = helpers.in_men;
                stack1 = foundHelper || depth0.in_men;
                if (typeof stack1 === functionType) {
                    stack1 = stack1.call(depth0, {
                        hash: {}
                    });
                }
                else if (stack1 === undef) {
                    stack1 = helperMissing.call(depth0, "in_men", {
                        hash: {}
                    });
                }
                buffer += escapeExpression(stack1) + "</li>\n ";
                return buffer;
            }
            buffer += "<ul>\n ";
            stack1 = "in_men";
            foundHelper = helpers.items;
            stack2 = foundHelper || depth0.items;
            foundHelper = helpers.nav5;
            stack3 = foundHelper || depth0.nav5;
            tmp1 = self.program(1, program1, data);
            tmp1.hash = {};
            tmp1.fn = tmp1;
            tmp1.inverse = self.noop;
            if (foundHelper && typeof stack3 === functionType) {
                stack1 = stack3.call(depth0, stack2, stack1, tmp1);
            }
            else {
                stack1 = blockHelperMissing.call(depth0, stack3, stack2, stack1, tmp1);
            }
            if (stack1 || stack1 === 0) {
                buffer += stack1;
            }
            buffer += "\n</ul>\n";
            return buffer;
        });
        return HandlebarsTemplates["public/templates/navigation-template"];
    }).call(this);;
}).call(this);
</script>
      
<script>
Benchmark.prototype.setup = function() {
  var data = {
    items: [{
      "name": "BLOUSE",
      "in_men": null,
      "in_women": 1,
      "in_unisex": null
    }, {
      "name": "TROUSERS",
      "in_men": 3,
      "in_women": 2,
      "in_unisex": null
    }, {
      "name": "2 PIECE SUIT",
      "in_men": null,
      "in_women": 3,
      "in_unisex": null
    }, {
      "name": "JACKET / COAT",
      "in_men": 4,
      "in_women": 4,
      "in_unisex": null
    }, {
      "name": "DRESS",
      "in_men": null,
      "in_women": 5,
      "in_unisex": null
    }, {
      "name": "OVERALL",
      "in_men": 5,
      "in_women": 6,
      "in_unisex": null
    }, {
      "name": "SKIRT",
      "in_men": null,
      "in_women": 7,
      "in_unisex": null
    }, {
      "name": "SHOE",
      "in_men": 6,
      "in_women": 8,
      "in_unisex": null
    }, {
      "name": "SPORT",
      "in_men": 7,
      "in_women": 9,
      "in_unisex": null
    }, {
      "name": "KNIT",
      "in_men": 8,
      "in_women": 10,
      "in_unisex": null
    }, {
      "name": "TOP",
      "in_men": 9,
      "in_women": 11,
      "in_unisex": null
    }, {
      "name": "UNDERWEAR/SLEEP",
      "in_men": 10,
      "in_women": 12,
      "in_unisex": null
    }, {
      "name": "WAISTCOAT",
      "in_men": 11,
      "in_women": 13,
      "in_unisex": null
    }, {
      "name": "SUIT",
      "in_men": 1,
      "in_women": null,
      "in_unisex": null
    }, {
      "name": "SHIRT",
      "in_men": 2,
      "in_women": null,
      "in_unisex": null
    }, {
      "name": "BAG",
      "in_men": null,
      "in_women": null,
      "in_unisex": 1
    }, {
      "name": "BELT",
      "in_men": null,
      "in_women": null,
      "in_unisex": 2
    }, {
      "name": "GLASSES",
      "in_men": null,
      "in_women": null,
      "in_unisex": 3
    }, {
      "name": "GLOVE",
      "in_men": null,
      "in_women": null,
      "in_unisex": 4
    }, {
      "name": "HAT",
      "in_men": null,
      "in_women": null,
      "in_unisex": 5
    }, {
      "name": "JEWELLERY",
      "in_men": null,
      "in_women": null,
      "in_unisex": 6
    }, {
      "name": "SCARF",
      "in_men": null,
      "in_women": null,
      "in_unisex": 7
    }, {
      "name": "SPECIAL",
      "in_men": null,
      "in_women": null,
      "in_unisex": 8
    }, {
      "name": "TIE",
      "in_men": null,
      "in_women": null,
      "in_unisex": 9
    }]
  };
  
  //first implementation
  
  Handlebars.registerHelper('nav1', function(array, gender, fn){
    var buffer = '';
  
    array = _.sortBy(array, function(item){ return item[gender] });
  
    for (var i = 0, j = array.length; i < j; i++){
      var item = array[i];
  
      if(typeof(item[gender]) === 'number'){
        buffer += fn(item);
      }
    }
  
    return buffer;
  });
  
  //first implementation readable
  
  Handlebars.registerHelper('nav2', function(array, gender, fn){
    var buffer = '';
  
    var sortedArray = _.sortBy(array, function(item){ return item[gender] });
  
    for (var i = 0, j = sortedArray.length; i < j; i++){
      var item = array[i];
  
      if(typeof(item[gender]) === 'number'){
        buffer += fn(item);
      }
    }
  
    return buffer;
  });
  
  // refactor with underscore
  
    Handlebars.registerHelper('nav3', function(array, gender, fn){
      array = _.filter(array, function(item)       { return typeof(item[gender]) === 'number'});
      array = _.sortBy(array, function(item)       { return item[gender] });
      return  _.reduce(array, function(memo, item) { return memo + fn(item); }, '');
    });
  
  // refactor with underscore one-line
  
  Handlebars.registerHelper('nav4', function(array, gender, fn){
    return  _.reduce(_.sortBy(_.filter(array, function(item){ return typeof(item[gender]) === 'number'}), function(item){ return item[gender] }), function(memo, item) { return memo + fn(item); }, '');
  });
  
  // refactor with underscore and precompiled template
  
  Handlebars.registerHelper('nav5', function(array, gender, fn){
      array = _.filter(array, function(item)       { return typeof(item[gender]) === 'number'});
      array = _.sortBy(array, function(item)       { return item[gender] });
      return  _.reduce(array, function(memo, item) { return memo + fn(item); }, '');
    });
  
  var template1 = Handlebars.compile($("#bench-template-1").html());
  var template2 = Handlebars.compile($("#bench-template-2").html());
  var template3 = Handlebars.compile($("#bench-template-3").html());
  var template4 = Handlebars.compile($("#bench-template-4").html());
  var template5 = HandlebarsTemplates["public/templates/navigation-template"](data);

};
</script>

Preparation code output

​<!-- precompiled bench-template-5 -->

Test runner

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

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
first implementation
template1(data)
pending…
first implementation readable
template2(data)
pending…
refactor with underscore
template3(data)
pending…
refactor with underscore one-line
template4(data)
pending…
refactor with underscore and precompiled template
HandlebarsTemplates["public/templates/navigation-template"](data);
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.

0 Comments