Skip to main content
Commonmark migration
Source Link

> test(1000, 100, 10)

 

object[key]: 163 ms

 

object[key] if changed: 172 ms

 

object[key] if changed & emit backbone event: 953 ms

 

Backbone.Model: 4043 ms

 

eventsBackboneCount: 100000

> test(1000, 100, 10)

 

object[key]: 163 ms

 

object[key] if changed: 172 ms

 

object[key] if changed & emit backbone event: 953 ms

 

Backbone.Model: 4043 ms

 

eventsBackboneCount: 100000

> test(1000, 100, 10)

object[key]: 163 ms

object[key] if changed: 172 ms

object[key] if changed & emit backbone event: 953 ms

Backbone.Model: 4043 ms

eventsBackboneCount: 100000

Tweeted twitter.com/#!/StackGameDev/status/308343661966540800
Source Link
v_y
  • 133
  • 2

Are javascript MVC model implementations too slow for games?

I wanted to implement a game in javascript with an MVC design pattern, with each entity's state stored in a model.

So for example,

In an update loop we iterate over all models and apply the velocity attribute to the position attribute of the model. A view associated with each entity/model would then receive a position changed event, and update the representation of the entity. This would happen independently of the views render method being called in a requestAnimationFrame callback.

What I found though, through a possibly naive implementation, is that setting attributes of a model is simply too slow. As much as I prefer the architecture of this code, the framerate was significantly lower.

Should I give up on using MVC for frequently updated attributes like position?

Below, I've included some code to test aspects of setting attributes of an object. The most minimal model-like behaviour, in which an attribute is set only when the new value differs from the current, and a "changed" update event is triggered, is about 10x slower than just setting attributes directly.

Output:

> test(1000, 100, 10)

object[key]: 163 ms

object[key] if changed: 172 ms

object[key] if changed & emit backbone event: 953 ms

Backbone.Model: 4043 ms

eventsBackboneCount: 100000

var test = function(creations, iterations, keyCount){
  var eventsBackbone = _.extend({}, Backbone.Events);
  var eventsBackboneCount = 0;
  eventsBackbone.on('all', function(){
    eventsBackboneCount = eventsBackboneCount + 1;
  });

  var looper = function(label, create, set){
    var start = (new Date()).getTime();

    var data = {};

    for(var i = 0; i < creations; i++){
      data[i] = create(i);
    }

    for(var j = 0; j < iterations; j++){
      for(var i = 0; i < creations; i++){
        var key = ''+(j % keyCount);
        set(data[i], key, Math.random());
      }
    }

    var end = (new Date()).getTime();

    console.log(''+label+': '+(end - start)+' ms');

    return data;
  };

  looper(
    'object[key]',
    function(id){
      return {};
    },
    function(datum, key, value){
      datum[key] = value;
    }
    );

  looper(
    'object[key] if changed',
    function(id){
      return {};
    },
    function(datum, key, value){
      if(datum[key] !== value){
        datum[key] = value;
     }
    }
    );

  looper(
    'object[key] if changed & emit backbone event',
    function(id){
      return {id:id};
    },
    function(datum, key, value){
      if(datum[key] !== value){
        datum[key] = value;
        eventsBackbone.trigger('changed:'+datum.id, datum, key);
     }
    }
    );

  looper(
    'Backbone.Model',
    function(id){
      return new Backbone.Model({});
    },
    function(datum, key, value){
      datum.set(key, value);
    }
    );

  console.log('eventsBackboneCount: '+eventsBackboneCount);
};