Handlebars Nav Helper

JavaScript performance comparison

Revision 4 of this test case created by ben

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.nav3;
            stack3 = foundHelper || depth0.nav3;
            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); }, '');
  });
  
  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"];

};
</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
1. first implementation
template1(data)
pending…
2. first implementation readable
template2(data)
pending…
3. refactor with underscore
template3(data)
pending…
4. refactor with underscore one-line
template4(data)
pending…
5. refactor with underscore and precompiled template
template5(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