Angular VS Knockout VS Ember VS Backbone (v172)

Revision 172 of this benchmark created on


Description

Comparison between Angular, Knockout and Ember. Added Backbone. Also with comparison of optimization during object creation.

Preparation HTML

<!-- Jquery -->
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<!-- Angular -->
<div ng-app>
  <p>Angular:</p>
  <span ng-controller="Ctrl" id="angList"><span ng-repeat="item in data">{{item}}</span></span>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

<script>
  var Ctrl = function($scope){
    $scope.data = [];
  }
  angular.element(document).ready(function() {
    window.ANGAPP = {
      scope: $('#angList').scope(),
      push: function(data){
        this.scope.data.push(data);
      },
      clear: function(){
        this.scope.data = [];
        this.scope.$digest();
      }
    };
  });
</script> 

<!-- Knockout -->
<div id="koapp">
  <p>Knockout:</p>
  <span data-bind="foreach: data"><span data-bind="text: $data"></span></span>
</div>

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js"></script>

<script>
  var KOData = ko.observableArray();
  var KOviewmodel = {data: KOData};
  
  ko.applyBindings(KOviewmodel, document.getElementById('koapp'));
  var KOclear = function (){
    KOData.splice(0, KOData().length);
  };
  var KOfastClear = function(){
    KOData([]);
  };
  var KOpush = function (data){
    KOData.push(data);
  };
  var KOunwrap = function(value){
    // Source: http://jsperf.com/ko-unwrapobservable/2
    return ('function'===typeof(value)) ? value(): value;
  };
</script>

<!-- Ember -->
<div id="emapp">
  <p>Ember:</p>
  <script type="text/x-handlebars">
    <span>
      {{#each EMapp.data}}<span>{{this}}</span>{{/each}}
    </span>
  </script>
</div>

<script src="http://builds.emberjs.com/handlebars-1.0.0-rc.4.js"></script>
<script src="http://builds.emberjs.com.s3.amazonaws.com/ember-1.0.0-rc.6.min.js"></script>

<script>
  EMapp = Ember.Application.create({
    rootElement: $('#emapp')
  });
  EMapp.data = Ember.A();
  
  EMclear = function () {
    EMapp.get('data').clear();
  };
  EMreset = function () {
    EMapp.set('data', Ember.A());
  };
  EMpush = function (data) {
    EMapp.get('data').pushObject(data);
  };
</script>

<!--Backbone-->
<script src="https://underscorejs.org/underscore.js"></script>
<script src="https://backbonejs.org/backbone.js"></script>

<div id="backboneapp">
  <h3>Backbone</h3>
  <span class="backbone-items"></span>
</div>

<script>
var backboneView = Backbone.View.extend({
  push: function(i) {
    this.$el.append(i);
  },
  clear: function() {
    this.$el.html('');
  }

});

window.BB = new backboneView({el: "#backboneapp .backbone-items"});
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Angular 100
ANGAPP.clear();
for (var i = 0; i < 100; i++)
  ANGAPP.push(i);
ANGAPP.scope.$digest();
ready
Angular 100 (mod)
ANGAPP.clear();
for (var i = 0; i < 100; i++)
  ANGAPP.push(i);
ANGAPP.scope.$digest();
ready
Knockout 100
KOclear();
for (var i = 0; i < 100; i++)
  KOpush(i);
ready
Knockout 100 (mod)
KOclear();
var list = ko.utils.unwrapObservable(KOData);
for (var i = 0; i < 100; i++)
  list.push(i);
KOData.valueHasMutated();
ready
Knockout 100 (unwrap mod)
KOclear();
var list = KOunwrap(KOData);
for (var i = 0; i < 100; i++)
  list.push(i);
KOData.valueHasMutated();
ready
Ember 100
EMclear();
for (var i = 0; i < 100; i++) {
  EMpush(i);
}
ready
Ember 100 (mod)
Ember.run(function() {
  EMclear();
  for (var i = 0; i < 100; i++) {
    EMpush(i);
  }
});
ready
Ember 100 (reset mod)
Ember.run(function() {
  EMreset();
  for (var i = 0; i < 100; i++) {
    EMpush(i);
  }
});
ready
Backbone
BB.clear();
for (var i = 0; i < 100; i++) {
  BB.push(i);
}
ready
Knockout 100 with fast clear
KOfastClear();
for (var i = 0; i < 100; i++)
  KOpush(i);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.