Skip to content

Commit

Permalink
added benchmark.js to measure performance improvements while investig…
Browse files Browse the repository at this point in the history
…ating #595
  • Loading branch information
justinbmeyer committed Dec 19, 2013
1 parent 104e6ef commit adb6af4
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 37 deletions.
3 changes: 2 additions & 1 deletion bower.json
Expand Up @@ -11,6 +11,7 @@
"license": "MIT",
"devDependencies": {
"qunit": "~1.12.0",
"zepto": "~1.0.0"
"zepto": "~1.0.0",
"benchmark": "~1.0.0"
}
}
6 changes: 4 additions & 2 deletions lib/stealconfig.js
Expand Up @@ -28,7 +28,8 @@
map: {
"*": {
"jquery/jquery.js": "jquery",
"can/util/util.js": "can/util/jquery/jquery.js"
"can/util/util.js": "can/util/jquery/jquery.js",
"benchmark/benchmark.js":"benchmark"
}
},
paths: {
Expand All @@ -38,7 +39,8 @@
"yui/yui.js": "lib/yui-3.7.3.js",
"zepto/zepto.js": "lib/zepto.1.0.js",
"can/": "",
"jquerypp/": "http://jquerypp.com/release/1.0.1/steal/"
"jquerypp/": "http://jquerypp.com/release/1.0.1/steal/",
"benchmark": "bower_components/benchmark/benchmark.js"
},
shim: {
jquery: {
Expand Down
7 changes: 7 additions & 0 deletions list/list.js
Expand Up @@ -79,11 +79,18 @@ steal("can/util","can/map", function(can, Map){
this.length = 0;
can.cid(this, ".map")
this._init = 1;
instances = instances || [];


if( can.isDeferred(instances) ) {
this.replace(instances)
} else {
var teardownMapping = instances.length && can.Map.helpers.addToMap(instances, this);
this.push.apply(this, can.makeArray(instances || []));
}

teardownMapping && teardownMapping();

// this change needs to be ignored
this.bind('change',can.proxy(this._changes,this));
can.simpleExtend(this, options);
Expand Down
18 changes: 18 additions & 0 deletions map/benchmark.html
@@ -0,0 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<h1 id="qunit-header">can.Map Test Suite</h1>

<h2 id="qunit-banner"></h2>

<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-test-area"></div>

<script type="text/javascript" src="../lib/steal/steal.js?can/map/map_benchmark.js"></script>
<script type="text/javascript"></script>
</body>
</html>
73 changes: 39 additions & 34 deletions map/map.js
Expand Up @@ -50,27 +50,6 @@ steal('can/util','can/util/bind','can/construct', 'can/util/batch',function(can,
// A map that temporarily houses a reference
// to maps that have already been made for a plain ole JS object
madeMap = null,
addToMap = function(obj, instance){
var teardown = false;
if(!madeMap){
teardown = true;
madeMap = {}
}
// record if it has a Cid before we add one
var hasCid = obj._cid;
var cid = can.cid(obj);

// only update if there already isn't one
if( !madeMap[cid] ){

madeMap[cid] = {
obj: obj,
instance: instance,
added: !hasCid
}
}
return teardown;
},
teardownMap = function(){
for(var cid in madeMap){
if(madeMap[cid].added) {
Expand All @@ -82,6 +61,7 @@ steal('can/util','can/util/bind','can/construct', 'can/util/batch',function(can,
getMapFromObject = function(obj){
return madeMap && madeMap[obj._cid] && madeMap[obj._cid].instance
};

/**
* @add can.Map
*/
Expand All @@ -99,9 +79,13 @@ steal('can/util','can/util/bind','can/construct', 'can/util/batch',function(can,
if(!this.defaults){
this.defaults = {};
}
// a list of the compute properties
this._computes = [];
for(var prop in this.prototype){
if(typeof this.prototype[prop] !== "function"){
this.defaults[prop] = this.prototype[prop];
} else if(this.prototype[prop].isComputed) {
this._computes.push(prop)
}
}
}
Expand All @@ -111,13 +95,36 @@ steal('can/util','can/util/bind','can/construct', 'can/util/batch',function(can,
}

},
_computes: [],
// keep so it can be overwritten
bind: can.bindAndSetup,
on: can.bindAndSetup,
unbind: can.unbindAndTeardown,
off: can.unbindAndTeardown,
id: "id",
helpers: {
addToMap: function(obj, instance){
var teardown;
if(!madeMap){
teardown = teardownMap;
madeMap = {}
}
// record if it has a Cid before we add one
var hasCid = obj._cid;
var cid = can.cid(obj);

// only update if there already isn't one
if( !madeMap[cid] ){

madeMap[cid] = {
obj: obj,
instance: instance,
added: !hasCid
}
}
return teardown;
},

canMakeObserve : function( obj ) {
return obj && !can.isDeferred(obj) && (can.isArray(obj) || can.isPlainObject( obj ) || ( obj instanceof can.Map ));
},
Expand Down Expand Up @@ -228,7 +235,7 @@ steal('can/util','can/util/bind','can/construct', 'can/util/batch',function(can,
// Sets all `attrs`.
this._init = 1;
this._setupComputes();
var teardownMapping = obj && addToMap(obj, this);
var teardownMapping = obj && can.Map.helpers.addToMap(obj, this);
/**
* @property {*} can.Map.prototype.DEFAULT-ATTR
*
Expand Down Expand Up @@ -263,9 +270,9 @@ steal('can/util','can/util/bind','can/construct', 'can/util/batch',function(can,
*/
var data = can.extend( can.extend(true,{},this.constructor.defaults || {}), obj )
this.attr(data);
if(teardownMapping){
teardownMap()
}

teardownMapping && teardownMapping()

this.bind('change',can.proxy(this._changes,this));

delete this._init;
Expand Down Expand Up @@ -358,17 +365,15 @@ steal('can/util','can/util/bind','can/construct', 'can/util/batch',function(can,
* Getter/Setter computes.
*/
_setupComputes: function(){
var prototype = this.constructor.prototype;
this._computedBindings = {}
for(var prop in prototype){
if(prototype[prop] && prototype[prop].isComputed){
this[prop] = prototype[prop].clone(this);
this._computedBindings[prop] = {
count: 0
}
var computes = this.constructor._computes;
this._computedBindings = {};
for(var i = 0, len = computes.length, prop; i< len; i++) {
prop = computes[i];
this[prop] = this[prop].clone(this);
this._computedBindings[prop] = {
count: 0
}
}

},
_bindsetup: makeBindSetup(),
_bindteardown: function(){
Expand Down
18 changes: 18 additions & 0 deletions map/map_benchmark.js
@@ -0,0 +1,18 @@
steal('can/map', 'can/list','can/test/benchmarks.js',function(Map, List, benchmarks){

benchmarks.add(
"Adding a big array to an object",
function(){
var map = new can.Map(),
objects = [];

for (var i = 0; i < 10; i++){
objects.push({prop: 'prop', nest: {prop: 'prop', nest: {prop: 'prop'}}})
}
},
function(){
map.attr('obj', objects)
});


})
33 changes: 33 additions & 0 deletions test/benchmarks.js
@@ -0,0 +1,33 @@
steal("steal","benchmark", function(steal){

var suite = new Benchmark.Suite;

suite.on('cycle', function(event) {
console.log(String(event.target));
})

var benchmarks = {
add: function(name, setup, benchmark){
if(!benchmark){
benchmark = setup;
setup = undefined
}
suite.add(name, benchmark, {
setup: setup
});
return this;
},
run: function(){
suite.run({ 'async': true, 'queued': true });
},
suite: suite,
on: function(){
return suite.on.apply(this, arguments)
}
}
steal.bind("done", function(){
benchmarks.run();
})

return benchmarks;
})
5 changes: 5 additions & 0 deletions util/jquery/jquery.js
Expand Up @@ -84,6 +84,11 @@ steal('jquery', 'can/util/can.js', 'can/util/array/each.js', "can/util/inserted"

}
return this;
},
proxy: function(fn, context){
return function(){
return fn.apply(context, arguments)
}
}
});

Expand Down

0 comments on commit adb6af4

Please sign in to comment.