yjs/bower_components/observe-js/benchmark/observation_benchmark.js
2014-12-14 17:00:02 +00:00

358 lines
9.0 KiB
JavaScript

/*
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
(function(global) {
'use strict';
var createObject = ('__proto__' in {}) ?
function(obj) { return obj; } :
function(obj) {
var proto = obj.__proto__;
if (!proto)
return obj;
var newObject = Object.create(proto);
Object.getOwnPropertyNames(obj).forEach(function(name) {
Object.defineProperty(newObject, name,
Object.getOwnPropertyDescriptor(obj, name));
});
return newObject;
};
function ObservationBenchmark(objectCount) {
Benchmark.call(this);
this.objectCount = objectCount;
}
ObservationBenchmark.prototype = createObject({
__proto__: Benchmark.prototype,
setup: function() {
this.mutations = 0;
if (this.objects)
return;
this.objects = [];
this.observers = [];
this.objectIndex = 0;
while (this.objects.length < this.objectCount) {
var obj = this.newObject();
this.objects.push(obj);
var observer = this.newObserver(obj);
observer.open(this.observerCallback, this);
this.observers.push(observer);
}
},
test: function(mutationCount) {
while (mutationCount > 0) {
var obj = this.objects[this.objectIndex];
mutationCount -= this.mutateObject(obj);
this.mutations++;
this.objectIndex++;
if (this.objectIndex == this.objects.length) {
this.objectIndex = 0;
}
}
},
cleanup: function() {
if (this.mutations !== 0)
alert('Error: mutationCount == ' + this.mutationCount);
this.mutations = 0;
},
dispose: function() {
this.objects = null;
while (this.observers.length) {
this.observers.pop().close();
}
this.observers = null;
if (Observer._allObserversCount != 0) {
alert('Observers leaked');
}
},
observerCallback: function() {
this.mutations--;
}
});
function SetupObservationBenchmark(objectCount) {
Benchmark.call(this);
this.objectCount = objectCount;
}
SetupObservationBenchmark.prototype = createObject({
__proto__: Benchmark.prototype,
setup: function() {
this.mutations = 0;
this.objects = [];
this.observers = [];
while (this.objects.length < this.objectCount) {
var obj = this.newObject();
this.objects.push(obj);
}
},
test: function() {
for (var i = 0; i < this.objects.length; i++) {
var obj = this.objects[i];
var observer = this.newObserver(obj);
observer.open(this.observerCallback, this);
this.observers.push(observer);
}
},
cleanup: function() {
while (this.observers.length) {
this.observers.pop().close();
}
if (Observer._allObserversCount != 0) {
alert('Observers leaked');
}
this.objects = null;
this.observers = null;
},
dispose: function() {
}
});
function ObjectBenchmark(config, objectCount) {
ObservationBenchmark.call(this, objectCount);
this.properties = [];
for (var i = 0; i < ObjectBenchmark.propertyCount; i++) {
this.properties.push(String.fromCharCode(97 + i));
}
}
ObjectBenchmark.configs = [];
ObjectBenchmark.propertyCount = 15;
ObjectBenchmark.prototype = createObject({
__proto__: ObservationBenchmark.prototype,
newObject: function() {
var obj = {};
for (var j = 0; j < ObjectBenchmark.propertyCount; j++)
obj[this.properties[j]] = j;
return obj;
},
newObserver: function(obj) {
return new ObjectObserver(obj);
},
mutateObject: function(obj) {
var size = Math.floor(ObjectBenchmark.propertyCount / 3);
for (var i = 0; i < size; i++) {
obj[this.properties[i]]++;
}
return size;
}
});
function SetupObjectBenchmark(config, objectCount) {
SetupObservationBenchmark.call(this, objectCount);
this.properties = [];
for (var i = 0; i < ObjectBenchmark.propertyCount; i++) {
this.properties.push(String.fromCharCode(97 + i));
}
}
SetupObjectBenchmark.configs = [];
SetupObjectBenchmark.propertyCount = 15;
SetupObjectBenchmark.prototype = createObject({
__proto__: SetupObservationBenchmark.prototype,
newObject: function() {
var obj = {};
for (var j = 0; j < SetupObjectBenchmark.propertyCount; j++)
obj[this.properties[j]] = j;
return obj;
},
newObserver: function(obj) {
return new ObjectObserver(obj);
}
});
function ArrayBenchmark(config, objectCount) {
ObservationBenchmark.call(this, objectCount);
var tokens = config.split('/');
this.operation = tokens[0];
this.undo = tokens[1];
};
ArrayBenchmark.configs = ['splice', 'update', 'push/pop', 'shift/unshift'];
ArrayBenchmark.elementCount = 100;
ArrayBenchmark.prototype = createObject({
__proto__: ObservationBenchmark.prototype,
newObject: function() {
var array = [];
for (var i = 0; i < ArrayBenchmark.elementCount; i++)
array.push(i);
return array;
},
newObserver: function(array) {
return new ArrayObserver(array);
},
mutateObject: function(array) {
switch (this.operation) {
case 'update':
var mutationsMade = 0;
var size = Math.floor(ArrayBenchmark.elementCount / 10);
for (var j = 0; j < size; j++) {
array[j*size] += 1;
mutationsMade++;
}
return mutationsMade;
case 'splice':
var size = Math.floor(ArrayBenchmark.elementCount / 5);
var removed = array.splice(size, size);
Array.prototype.splice.apply(array, [size*2, 0].concat(removed));
return size * 2;
default:
var val = array[this.undo]();
array[this.operation](val + 1);
return 2;
}
}
});
function SetupArrayBenchmark(config, objectCount) {
ObservationBenchmark.call(this, objectCount);
};
SetupArrayBenchmark.configs = [];
SetupArrayBenchmark.propertyCount = 15;
SetupArrayBenchmark.prototype = createObject({
__proto__: SetupObservationBenchmark.prototype,
newObject: function() {
var array = [];
for (var i = 0; i < ArrayBenchmark.elementCount; i++)
array.push(i);
return array;
},
newObserver: function(array) {
return new ArrayObserver(array);
}
});
function PathBenchmark(config, objectCount) {
ObservationBenchmark.call(this, objectCount);
this.leaf = config === 'leaf';
this.path = Path.get('foo.bar.baz');
this.firstPathProp = Path.get(this.path[0]);
}
PathBenchmark.configs = ['leaf', 'root'];
PathBenchmark.prototype = createObject({
__proto__: ObservationBenchmark.prototype,
newPath: function(parts, value) {
var obj = {};
var ref = obj;
var prop;
for (var i = 0; i < parts.length - 1; i++) {
prop = parts[i];
ref[prop] = {};
ref = ref[prop];
}
prop = parts[parts.length - 1];
ref[prop] = value;
return obj;
},
newObject: function() {
return this.newPath(this.path, 1);
},
newObserver: function(obj) {
return new PathObserver(obj, this.path);
},
mutateObject: function(obj) {
var val = this.path.getValueFrom(obj);
if (this.leaf) {
this.path.setValueFrom(obj, val + 1);
} else {
this.firstPathProp.setValueFrom(obj, this.newPath(this.path.slice(1), val + 1));
}
return 1;
}
});
function SetupPathBenchmark(config, objectCount) {
ObservationBenchmark.call(this, objectCount);
this.path = Path.get('foo.bar.baz');
}
SetupPathBenchmark.configs = [];
SetupPathBenchmark.prototype = createObject({
__proto__: SetupObservationBenchmark.prototype,
newPath: function(parts, value) {
var obj = {};
var ref = obj;
var prop;
for (var i = 0; i < parts.length - 1; i++) {
prop = parts[i];
ref[prop] = {};
ref = ref[prop];
}
prop = parts[parts.length - 1];
ref[prop] = value;
return obj;
},
newObject: function() {
return this.newPath(this.path, 1);
},
newObserver: function(obj) {
return new PathObserver(obj, this.path);
}
});
global.ObjectBenchmark = ObjectBenchmark;
global.SetupObjectBenchmark = SetupObjectBenchmark;
global.ArrayBenchmark = ArrayBenchmark;
global.SetupArrayBenchmark = SetupArrayBenchmark;
global.PathBenchmark = PathBenchmark;
global.SetupPathBenchmark = SetupPathBenchmark;
})(this);