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
<!-- Jquery --> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/ember.js/1.5.1/ember.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/react/0.10.0/react.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/mithril/0.1.12/mithril.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/vue/0.10.4/vue.min.js"></script>
<!-- Angular --> <div ng-app> Angular: <span ng-controller="Ctrl" id="angList"><span ng-repeat="item in data">{{item}}</span></span> </div>
<!-- Knockout --> <div id="koapp"> <p>Knockout:</p>
Cart: <span data-bind="text: kocart().name"></span>
<div data-bind="foreach: kocart().vmLineItems"> <table> <tr> <td><span data-bind="text: ID"></span></td> <td><label>Part:</label><span data-bind="text: vmPart().partDisplayName"></span></td> <td> <label>Qty:</label><input data-bind="value: quantity().value"></input> <span data-bind="text: quantity().unitofmeasure"></span> </td> </tr> </table> </div>
</div>
<!-- Ember -->
<div id="emapp"></div> <script type="text/x-handlebars"> Ember: <span> {{#each EMapp.data}}<span>{{this}}</span>{{/each}} </span> </script>
<!-- React --> <div id="react"> React: <span id="reactMountNode"></span> </div>
<!-- Mithril --> <div id="mithrilapp"> Mithril: <span id="mithrilMountNode"></span> </div>
<!-- Vuejs --> <div id="vuejs"> Vuejs: <span id="vuejsMountNode"><span v-repeat="item: data">{{ item }}</span></span> </div>
<script> var j = -1, MOD = 1000; var Ctrl = function($scope){ $scope.data = []; };
var cart10 = '{"cartuuid":"28ced139-2b1a-4a01-8a7a-9c073681b8b4","id":0,"vmLineItems":[{"ID":"1","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"110002","sourceCode":""}},{"ID":"2","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"110003","sourceCode":""}},{"ID":"3","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"110004","sourceCode":""}},{"ID":"4","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"110253","sourceCode":""}},{"ID":"5","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"110248","sourceCode":""}},{"ID":"6","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"12-8V12.50","sourceCode":""}},{"ID":"7","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"1-3V10.60","sourceCode":""}},{"ID":"8","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"14-160-17","sourceCode":""}},{"ID":"9","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"150-380815","sourceCode":""}},{"ID":"10","quantity":{"unitofmeasure":"each","value":1.0},"vmPart":{"partNumber":"16002600210","sourceCode":""}}]}';
var ENV = {EXTEND_PROTOTYPES: false};
var ReactComponent = React.createClass({displayName: 'PerfTest', getInitialState: function() { return { data: [] }; }, render: function() {
<span class="kw1">return</span> <span class="br0">(</span><br> React.<span class="me1">DOM</span>.<span class="me1">span</span><span class="br0">(</span><span class="kw2">null</span><span class="sy0">,</span> <br> <span class="kw1">this</span>.<span class="me1">state</span>.<span class="me1">data</span>.<span class="me1">map</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span>result<span class="br0">)</span> <span class="br0">{</span><br> <span class="kw1">return</span> React.<span class="me1">DOM</span>.<span class="me1">span</span><span class="br0">(</span> <span class="br0">{</span>key<span class="sy0">:</span>result.<span class="me1">id</span><span class="br0">}</span><span class="sy0">,</span> result.<span class="me1">text</span><span class="br0">)</span><span class="sy0">;</span><br> <span class="br0">}</span><span class="br0">)</span><br> <span class="br0">)</span><br><span class="br0">)</span><span class="sy0">;</span>
} });
var MithrilData = new Array(); var mithapp = { controller: function() { this.data = MithrilData; }, view: function(ctrl) { return m("span", [ctrl.data.map(function(datum) { return m('span', datum); })]); } }
$(document).ready(function() { angular.element(document).ready(function() { var ang_scope = $('#angList').scope();
window.<span class="me1">ANGclear</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span><span class="br0">{</span><br> j <span class="sy0">=</span> <span class="br0">(</span>j <span class="sy0">+</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy0">%</span>MOD<span class="sy0">;</span><br> ang_scope.<span class="me1">data</span>.<span class="me1">splice</span><span class="br0">(</span><span class="nu0">0</span><span class="sy0">,</span> ang_scope.<span class="me1">data</span>.<span class="me1">length</span><span class="br0">)</span><br> ang_scope.$apply<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br><span class="br0">}</span><span class="sy0">;</span><br>window.<span class="me1">ANGpush</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">(</span>data<span class="br0">)</span><span class="br0">{</span><br> ang_scope.<span class="me1">data</span>.<span class="me1">push</span><span class="br0">(</span>data<span class="sy0">+</span><span class="st0">"_"</span><span class="sy0">+</span>ang_scope.<span class="me1">data</span>.<span class="me1">length</span><span class="sy0">+</span><span class="st0">" "</span><span class="br0">)</span><span class="sy0">;</span><br> ang_scope.$apply<span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br><span class="br0">}</span><span class="sy0">;</span>
});
/** Knockout **/ function KOPart(part) { var self = this; self.partNumber = ko.observable(part.partNumber); self.sourceCode = ko.observable(part.sourceCode);
<span class="kw1">this</span>.<span class="me1">partDisplayName</span> <span class="sy0">=</span> ko.<span class="me1">computed</span><span class="br0">(</span><span class="kw2">function</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span><br> <span class="kw1">return</span> self.<span class="me1">partNumber</span><span class="br0">(</span><span class="br0">)</span> <span class="sy0">+</span> <span class="st0">' '</span> <span class="sy0">+</span> self.<span class="me1">sourceCode</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br><span class="br0">}</span><span class="br0">)</span><span class="sy0">;</span>
}
function KOQuantity(value, unitofmeasure) { this.value = ko.observable(value); this.unitofmeasure = ko.observable(unitofmeasure); }
function KOLine(item) { this.ID = ko.observable(item.ID); this.quantity = ko.observable(new KOQuantity(item.quantity.value, item.quantity.unitofmeasure)); //this.quantityOpts = ko.observableArray([ item.quantity.unitofmeasure, "foo", "bar" ]);
<span class="kw1">this</span>.<span class="me1">vmPart</span> <span class="sy0">=</span> ko.<span class="me1">observable</span><span class="br0">(</span><span class="kw2">new</span> KOPart<span class="br0">(</span><span class="kw1">item</span>.<span class="me1">vmPart</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span>
}
function KOCart(data) { this.name = data.name; this.cartuuid = data.cartuuid; this.id = data.id; this.vmLineItems = ko.observableArray([]); var mappedLines = $.map(data.vmLineItems, function(item) { return new KOLine(item) }); this.vmLineItems(mappedLines); }
function CartViewModel(data) { var self = this; self.kocart = ko.observable("yo"); console.log("before data is bound"); self.kocart(new KOCart(data)); console.log("AFTER data is bound");
self.<span class="me1">setCart</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">(</span>cartData<span class="br0">)</span> <span class="br0">{</span><br> self.<span class="me1">kocart</span><span class="br0">(</span><span class="kw2">new</span> KOCart<span class="br0">(</span>allData<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br> <span class="br0">}</span><span class="sy0">;</span>
}
var koViewModel = new CartViewModel({}); ko.applyBindings(koViewModel , document.getElementById('koapp'));
window.KOclear = function (){ j = (j + 1)%MOD; KOData.splice(0, koViewModel.kocart.vmLineItems.length); }; window.KOpush = function (data){ KOData.push(data+"_"+koViewModel.kocart.vmLineItems.length+" "); };
/** Knockout **/
EMapp = Ember.Application.create({ rootElement: '#emapp' }); EMapp.data = Ember.A();
window.EMclear = function () { j = (j + 1)%MOD; EMapp.data.clear(); }; window.EMpush = function (data) { EMapp.data.pushObject(data+"_"+EMapp.data.length+" "); };
var reactComp = ReactComponent(); React.renderComponent(reactComp, $('#reactMountNode')[0]);
window.RClear = function() { j = (j + 1)%MOD; reactComp.setState({data: []}) };
window.RPush = function(data) { var stateData = reactComp.state.data; stateData.push(data+"_"+reactComp.state.data.length+" "); reactComp.setState({data: stateData}); }
m.module(document.getElementById("mithrilMountNode"), mithapp); window.Mclear = function() { j = (j + 1)%MOD; m.startComputation(); MithrilData.splice(0); m.endComputation(); };
window.Mpush = function(data) { m.startComputation(); MithrilData.push(data+"_"+MithrilData.length+" "); m.endComputation(); }
var vueInstance = new Vue({ el: '#vuejsMountNode', data: { data: [] } });
window.VueClear = function(){ j = (j + 1)%MOD; vueInstance.$set('data', []); }; window.VuePush = function(data){ var currentArr = vueInstance.$get('data'); currentArr.push(data+"_"+currentArr.length+" "); vueInstance.$set('data', currentArr); };
}); </script>
koViewModel.kocart.vmLineItems.length
Ready to run.
Test | Ops/sec | |
---|---|---|
Knockout-10 |
| ready |
Angular-10 |
| ready |
Mithril-10 |
| ready |
Ember-10 |
| ready |
React-10 |
| ready |
Vuejs-10 |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.