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
To test performance of jQuery template for outputting 100 rows each with 15 columns where the columns have fields that can trigger events.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://github.com/mhevery/mustache.js/raw/dot-notation/mustache.js"></script>
<script src="http://github.com/pvande/Milk/raw/master/dist/v1.2.0/milk.js"></script>
<script src="https://raw.github.com/Shopify/batman/master/lib/dist/batman.min.js"></script>
<script src="https://raw.github.com/BorisMoore/jsrender/master/jsrender.js"></script>
<script src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js" type="text/javascript"></script>
<script src="https://github.com/andyet/ICanHaz.js/raw/master/ICanHaz.min.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<script type="text/javascript">
$(function() {
$('body').delegate('#table .edit a, #table .select a', 'click', function() {
var $td = $(this).closest('td');
$td.find('input, select').show();
$td.find('a').hide();
});
$('body').delegate('#table .edit .cancel, $table .select .cancel', 'click', function() {
var $td = $(this).closest('td');
$td.find('input, select').hide();
$td.find('a').show();
});
});
function DummyFunction() {
var prefix = "Hello";
var suffix = "Wolrd!";
var greeting = prefix + " " + suffix;
alert(greeting);
}
</script>
<script type="text/x-jquery-tmpl" id="jqueryTmpl">
<tr>
<td>
<td><input type="checkbox" value="${id}" /></td>
<td>${name}</td>
<td>${custName}</td>
<td>${winlost}</td>
<td>${turnover}</td>
<td>${margin}</td>
<td>${betcount}</td>
<td><div class="ipViewLink" onclick="DummyFunction();">${ip}</div></td>
<td>${hasData}</td>
<td>${sporttypeId}</td>
<td>${sporttypeName}</td>
<td class="edit">
<a>Edit</a>
<input style="display:none;" type="hidden" value="Blah" />
<input class="cancel" type="button" value="cancel" />
</td>
<td class="select">
<a>Select</a>
<select style="display:none;">
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
<input class="cancel" type="button" value="cancel" />
</td>
<td>More string</td>
<td>More string</td>
</tr>
</script>
<script id="jsrendertmpl" type="text/x-jsrender">
{{for rows}}
<tr>
<td><input type = 'checkbox' value = '{{:id}}' /></td>
<td>{{:name}}</td>
<td>{{:custName}}</td>
<td>{{:winlost}}</td>
<td>{{:turnover}}</td>
<td>{{:margin}}</td>
<td>{{:betcount}}</td>
<td><div class='ipViewLink' onclick='DummyFunction();'>{{:ip}}</div></td>
<td>{{:hasData}}</td>
<td>{{:sporttypeId}}</td>
<td>{{:sporttypeName}}</td>
<td class = 'edit'>
<a>Edit</a>
<input style='display:none;' type='hidden' value='Blah' />
<input class = 'cancel' type = 'button' value = 'cancel' />
</td>
<td class='select'>
<a>Select</a>
<select style = 'display:none;'>
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
<input class = 'cancel' type = 'button' value = 'cancel' />
</td>
<td>More string</td>
<td>More string</td>
</tr>
{{/for}}
</script>
<script type="text/x-handlebars-template" id="handlebarsTmpl">
{{#each rows}}
{{#with this}}
<tr>
<td><input type = "checkbox" value = "{{id}}" /></td>
<td>{{name}}</td>
<td>{{custName}}</td>
<td>{{winlost}}</td>
<td>{{turnover}}</td>
<td>{{margin}}</td>
<td>{{betcount}}</td>
<td><div class="ipViewLink" onclick="DummyFunction();">{{ip}}</div></td>
<td>{{hasData}}</td>
<td>{{sporttypeId}}</td>
<td>{{sporttypeName}}</td>
<td class = 'edit'>
<a>Edit</a>
<input style='display:none;' type='hidden' value='Blah' />
<input class = 'cancel' type = 'button' value = 'cancel' />
</td>
<td class='select'>
<a>Select</a>
<select style = 'display:none;'>
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
<input class = 'cancel' type = 'button' value = 'cancel' />
</td>
<td>More string</td>
<td>More string</td>
</tr>
{{/with}}
{{/each}}
</script>
<script type="text/html" id="icanhazTmpl">
{{#rows}}
<tr>
<td><input type = "checkbox" value = "{{id}}" /></td>
<td>{{name}}</td>
<td>{{custName}}</td>
<td>{{winlost}}</td>
<td>{{turnover}}</td>
<td>{{margin}}</td>
<td>{{betcount}}</td>
<td><div class="ipViewLink" onclick="DummyFunction();">{{ip}}</div></td>
<td>{{hasData}}</td>
<td>{{sporttypeId}}</td>
<td>{{sporttypeName}}</td>
<td class = 'edit'>
<a>Edit</a>
<input style='display:none;' type='hidden' value='Blah' />
<input class = 'cancel' type = 'button' value = 'cancel' />
</td>
<td class='select'>
<a>Select</a>
<select style = 'display:none;'>
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
<input class = 'cancel' type = 'button' value = 'cancel' />
</td>
<td>More string</td>
<td>More string</td>
</tr>
{{/rows}}
</script>
<script>
var data = [];
var numberOfRow = 100;
for (var i = 0; i < numberOfRow; i++) {
var row = {
id: i,
name: 'punter' + i,
custName: 'andrew',
winlost: (i * 2.2).toFixed(2),
turnover: i,
margin: i + '%',
betcount: i,
ip: '127.127.127.127',
hasData: false,
sporttypeId: 1,
sporttypeName: 'Soccer'
};
data.push(row);
}
$.template("precompiledJqueryTmpl", document.getElementById("jqueryTmpl").innerHTML);
var underscoreTmpl = "\
<%for(var i=0;i<rows.length;i++){%>\
<%var row=rows[i];%> \
<tr>\
<td><input type = 'checkbox' value = '<%= row.id%>' /></td>\
<td><%= row.name%></td>\
<td><%= row.custName%></td>\
<td><%= row.winlost%></td>\
<td><%= row.turnover%></td>\
<td><%= row.margin%></td>\
<td><%= row.betcount%></td>\
<td><div class='ipViewLink' onclick='DummyFunction();'><%= row.ip%></div></td>\
<td><%= row.hasData%></td>\
<td><%= row.sporttypeId%></td>\
<td><%= row.sporttypeName%></td>\
<td class = 'edit'>\
<a>Edit</a>\
<input style='display:none;' type='hidden' value='Blah' />\
<input class = 'cancel' type = 'button' value = 'cancel' />\
</td>\
<td class='select'>\
<a>Select</a> \
<select style = 'display:none;'>\
<option>0</option>\
<option>1</option>\
<option>2</option>\
<option>3</option>\
<option>4</option>\
<option>5</option>\
<option>6</option>\
<option>7</option>\
<option>8</option>\
<option>9</option>\
<option>10</option>\
</select>\
<input class = 'cancel' type = 'button' value = 'cancel' />\
</td>\
<td>More string</td> \
<td>More string</td>\
</tr ><%}%>";
var mustacheTmpl="\
{{#rows}}\
<tr>\
<td><input type = 'checkbox' value = '{{id}}' /></td>\
<td>{{name}}</td>\
<td>{{custName}}</td>\
<td>{{winlost}}</td>\
<td>{{turnover}}</td>\
<td>{{margin}}</td>\
<td>{{betcount}}</td>\
<td><div class='ipViewLink' onclick='DummyFunction();'>{{ip}}</div></td>\
<td>{{hasData}}</td>\
<td>{{sporttypeId}}</td>\
<td>{{sporttypeId}}</td>\
<td class = 'edit'>\
<a>Edit</a>\
<input style='display:none;' type='hidden' value='Blah' />\
<input class = 'cancel' type = 'button' value = 'cancel' />\
</td>\
<td class='select'>\
<a>Select</a>\
<select style = 'display:none;'>\
<option>0</option>\
<option>1</option>\
<option>2</option>\
<option>3</option>\
<option>4</option>\
<option>5</option>\
<option>6</option>\
<option>7</option>\
<option>8</option>\
<option>9</option>\
<option>10</option>\
</select>\
<input class = 'cancel' type = 'button' value = 'cancel' />\
</td>\
<td>More string</td>\
<td>More string</td>\
</tr >{{/rows}}";
var milkTmpl="\
{{#rows}}\
<tr>\
<td><input type = 'checkbox' value = '{{id}}' /> </td>\
<td>{{name}}</td>\
<td>{{custName}}</td>\
<td>{{winlost}}</td>\
<td>{{turnover}}</td>\
<td>{{margin}}</td>\
<td>{{betcount}}</td>\
<td><div class='ipViewLink' onclick='DummyFunction();'>{{ip}}</div></td>\
<td>{{hasData}}</td>\
<td>{{sporttypeId}}</td>\
<td>{{sporttypeName}}</td>\
<td class = 'edit'>\
<a> Edit </a>\
<input style='display:none;' type='hidden' value='Blah' />\
<input class = 'cancel' type = 'button' value = 'cancel' />\
</td>\
<td class='select'>\
<a>Select</a>\
<select style = 'display:none;'>\
<option>0</option>\
<option>1</option>\
<option>2</option>\
<option>3</option>\
<option>4</option>\
<option>5</option>\
<option>6</option>\
<option>7</option>\
<option>8</option>\
<option>9</option>\
<option>10</option>\
</select> \
<input class = 'cancel' type = 'button' value = 'cancel' />\
</td>\
<td>More string</td>\
<td>More string</td>\
</tr >{{/rows}}";
var jsRenderTmpl = $.templates( "#jsrendertmpl" );
var handlebarsTmpl = Handlebars.compile($("#handlebarsTmpl").html());
</script>
var numberOfRow = 100;
Ready to run.
Test | Ops/sec | |
---|---|---|
JQueryTemplate |
| ready |
PrecompiledJQueryTemplate |
| ready |
StringPaddingMethod |
| ready |
Underscore.js |
| ready |
Mustache.js |
| ready |
MustacheMilk |
| ready |
StringPaddingMethod02 |
| ready |
Jsrender |
| ready |
Handlebars.js |
| ready |
ICanHaz.js |
| ready |
StringPaddingMethod03 |
| ready |
StringPaddingMethod04 |
| ready |
StringConcat |
| ready |
StringConcatVer02 |
| ready |
StringConcatVer03 |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.