jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
<!-- Targeted DIV -->
<div id="target" style="display: none;"></div>
<!-- Libraries -->
<script src="https://code.jquery.com/jquery-git2.js"></script>
<script src="https://rawgithub.com/eugenioclrc/handlehash.js/master/HandleHash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.8.1/mustache.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hogan.js/3.0.0/hogan.min.js"></script>
<script src="https://rawgithub.com/olado/doT/master/doT.js"></script>
<script src="https://gsf.github.io/whiskers.js/whiskers.min.js"></script>
<script src="https://qatrix.com/js/qatrix-1.1.min.js"></script>
<script src="https://rawgithub.com/premasagar/875670/raw/d52752ead19a4eebc7237602438ae08a2541a5b5/tim-lite-cached-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.11.2/react.min.js"></script>
sharedVariables = {
header: "Header",
header2: "Header 2",
header3: "Header 3",
header4: "Header 4",
header5: "Header 5",
header6: "Header 6",
list: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
};
var element = document.getElementById('target');
hoganCompile = Hogan.compile("<div><h1 class='header'>{{{header}}}</h1><h2>class='header2'>{{{header2}}}</h2><h3 class='header3'>{{{header3}}}</h3><h4 class='header4'>{{{header4}}}</h4><h5 class='header5'>{{{header5}}}</h5><h6 class='header6'>{{{header6}}}</h6><ul class='list'>{{#list}}<li class='item'>{{{.}}}</li>{{/list}}</ul></div>");
handleHashTemplate = HandleHash.build("<div><h1>{#=data.header#}</h1><h2 class='header2'>{#=data.header2 #}</h2><h3 class='header3'>{#= data.header3 #}</h3><h4 class='header4'>{#= data.header4 #}</h4><h5 class='header5'>{#= data.header5 #}</h5><h6 class='header6'>{#= data.header6 #}</h6><ul class='list'>{#for(data.list,item) #}<li class='item'>{#= item #}</li>{#endfor #</ul></div>");
mustacheTemplate = "<div><h1 class='header'>{{{header}}}</h1><h2 class='header2'>{{{header2}}}</h2><h3 class='header3'>{{{header3}}}</h3><h4 class='header4'>{{{header4}}}</h4><h5 class='header5'>{{{header5}}}</h5><h6 class='header6'>{{{header6}}}</h6><ul class='list'>{{#list}}<li class='item'>{{{.}}}</li>{{/list}}</ul></div>";
//mustacheCompiledTemplate = Mustache.compile(mustacheTemplate);
//underscoreTemplate = _.template("<div><h1 class='header'><%= header %></h1><h2 class='header2'><%= header2 %></h2><h3 class='header3'><%= header3 %></h3><h4 class='header4'><%= header4 %></h4><h5 class='header5'><%= header5 %></h5><h6 class='header6'><%= header6 %></h6><ul class='list'><% for (var i = 0, l = list.length; i < l; i++) { %><li class='item'><%= list[i] %></li><% } %></ul></div>");
//underscoreTemplateEach = _.template("<div><h1 class='header'><%= header %></h1><h2 class='header2'><%= header2 %></h2><h3 class='header3'><%= header3 %></h3><h4 class='header4'><%= header4 %></h4><h5 class='header5'><%= header5 %></h5><h6 class='header6'><%= header6 %></h6><ul class='list'><% _.each(list, function(item){ %><li class='item'><%= item %></li><% }); %></ul></div>");
//underscoreTemplateEachCached = _.memoize(_.template("<div><h1 class='header'><%= header %></h1><h2 class='header2'><%= header2 %></h2><h3 class='header3'><%= header3 %></h3><h4 class='header4'><%= header4 %></h4><h5 class='header5'><%= header5 %></h5><h6 class='header6'><%= header6 %></h6><ul class='list'><% _.each(list, function(item){ %><li class='item'><%= item %></li><% }); %></ul></div>"), function (v) {
return v
});
//underscoreTemplateCached = _.memoize(_.template("<div><h1 class='header'><%= header %></h1><h2 class='header2'><%= header2 %></h2><h3 class='header3'><%= header3 %></h3><h4 class='header4'><%= header4 %></h4><h5 class='header5'><%= header5 %></h5><h6 class='header6'><%= header6 %></h6><ul class='list'><% for (var i = 0, l = list.length; i < l; i++) { %><li class='item'><%= list[i] %></li><% } %></ul></div>"), function (v) {
return v
});
//handlebarsTemplate = Handlebars.compile("<div><h1 class='header'>{{header}}</h1><h2 class='header2'>{{header2}}</h2><h3 class='header3'>{{header3}}</h3><h4 class='header4'>{{header4}}</h4><h5 class='header5'>{{header5}}</h5><h6 class='header6'>{{header6}}</h6><ul class='list'>{{#each list}}<li class='item'>{{this}}</li>{{/each}}</ul></div>");
doTtemplate = doT.template("<div><h1 class='header'>{{=it.header}}</h1><h2 class='header2'>{{=it.header2}}</h2><h3 class='header3'>{{=it.header3}}</h3><h4 class='header4'>{{=it.header4}}</h4><h5 class='header5'>{{=it.header5}}</h5><h6 class='header6'>{{=it.header6}}</h6><ul class='list'>{{for(var i = 0,l=it.list.length;i<l;i++) { }}<li class='item'>{{=it.list[i]}}</li>{{ } }}</ul></div>");
doTtemplate2 = doT.compile("<div><h1 class='header'>{{=it.header}}</h1><h2 class='header2'>{{=it.header2}}</h2><h3 class='header3'>{{=it.header3}}</h3><h4 class='header4'>{{=it.header4}}</h4><h5 class='header5'>{{=it.header5}}</h5><h6 class='header6'>{{=it.header6}}</h6><ul class='list'>{{~it.list :value:index}}<li class='item'>{{=value}}</li>{{~}}</ul></div>", {
append: true
});
whiskersRender = whiskers.compile("<div><h1 class='header'>{header}</h1><h2 class='header2'>{header2}</h2><h3 class='header3'>{header3}</h3><h4 class='header4'>{header4}</h4><h5 class='header5'>{header5}</h5><h6 class='header6'>{header6}</h6><ul class='list'>{for item in list}<li class='item'>{item}</li>{/for}</ul></div>");
//Resig Template Function (modified to support ')
function tmpl(str) {
var strFunc =
"var p=[];" +
"with(obj){p.push('" +
str.replace(/[\r\t\n]/g, " ")
.replace(/'(?=[^#]*#>)/g, "\t")
.split("'").join("\\'")
.split("\t").join("'")
.replace(/<#=(.+?)#>/g, "',$1,'")
.split("<#").join("');")
.split("#>").join("p.push('") + "');}return p.join('');";
return new Function("obj", strFunc);
}
resig = tmpl("<div><h1 class='header'><#= header #></h1><h2 class='header2'><#= header2 #></h2><h3 class='header3'><#= header3 #></h3><h4 class='header4'><#= header4 #></h4><h5 class='header5'><#= header5 #></h5><h6 class='header6'><#= header6 #></h6><ul class='list'><# for (var i = 0, l = list.length; i < l; i++) { #><li class='item'><#= list[i] #></li><# } #></ul></div>");
//Resig modified template function (no "with" block)
function tmpl2(str) {
var strFunc =
"var o='';" +
"o='" +
str.replace(/[\r\t\n]/g, " ")
.replace(/'(?=[^#]*#>)/g, "\t")
.split("'").join("\\'")
.split("\t").join("'")
.replace(/<#=(.+?)#>/g, "'+($1)+'")
.split("<#").join("';")
.split("#>").join("o+='") + "';return o;";
return new Function("data", strFunc);
}
resig2 = tmpl2("<div><h1 class='header'><#= data.header #></h1><h2 class='header2'><#= data.header2 #></h2><h3 class='header3'><#= data.header3 #></h3><h4 class='header4'><#= data.header4 #></h4><h5 class='header5'><#= data.header5 #></h5><h6 class='header6'><#= data.header6 #></h6><ul class='list'><# for (var i = 0, l = data.list.length; i < l; i++) { #><li class='item'><#= data.list[i] #></li><# } #></ul></div>");
var App = App || {};
App.template = '<div>' +
'<h1 class="header"><%this.header%></h1>' +
'<h2 class="header2"><%this.header2%></h2>' +
'<h3 class="header3"><%this.header3%></h3>' +
'<h4 class="header4"><%this.header4%></h4>' +
'<h5 class="header5"><%this.header5%></h5>' +
'<h6 class="header6"><%this.header6%></h6>' +
'<ul class="list">' +
'<%for(var i in this.list) {%>' +
'<li class="item"><%this.list[i]%></li>' +
'<%}%>' +
'</ul>' +
+'</div>'
App.render = function(html, options) {
var re = /<%([^%>]+)?%>/g, reExp = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g, code = 'var r=[];\n', cursor = 0;
var add = function(line, js) {
js? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') :
(code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
return add;
}
while(match = re.exec(html)) {
add(html.slice(cursor, match.index))(match[1], true);
cursor = match.index + match[0].length;
}
add(html.substr(cursor, html.length - cursor));
code += 'return r.join("");';
return new Function(code.replace(/[\r\t\n]/g, '')).apply(options);
}
var Hello = React.createClass({
render: function() {
return React.DOM.div({}, '<h1 class="header">' + this.props.header + '</h1>');
}
});
Ready to run.
Test | Ops/sec | |
---|---|---|
mustache.js |
| ready |
underscore.js |
| ready |
handlebar.js |
| ready |
Hogan.js |
| ready |
Resig Micro Templates (modified) |
| ready |
Resig Micro Templates (No "with" block) |
| ready |
underscore.js (_.each) |
| ready |
Mustache (compiled) |
| ready |
HandleHash |
| ready |
underscore each cached |
| ready |
underscore for cached |
| ready |
doT.js |
| ready |
doT.js 2 |
| ready |
Whiskers.js |
| ready |
React |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.