feat(change_detection): update change detection benchmark

This commit is contained in:
vsavkin 2015-01-27 18:01:05 -08:00 committed by Alex Eagle
parent 709df12b10
commit 3067601961
3 changed files with 101 additions and 62 deletions

View File

@ -6,13 +6,24 @@ describe('ng2 change detection benchmark', function () {
afterEach(perfUtil.verifyNoBrowserErrors); afterEach(perfUtil.verifyNoBrowserErrors);
it('should log ng stats', function() { it('should log ng stats (dynamic)', function() {
perfUtil.runClickBenchmark({ perfUtil.runClickBenchmark({
url: URL, url: URL,
buttons: ['#ng2DetectChanges'], buttons: ['#ng2ChangeDetectionDynamic'],
id: 'ng2.changeDetection', id: 'ng2.changeDetection.dynamic',
params: [{ params: [{
name: 'iterations', value: 500000, scale: 'linear' name: 'numberOfChecks', value: 900000, scale: 'linear'
}]
});
});
it('should log ng stats (jit)', function() {
perfUtil.runClickBenchmark({
url: URL,
buttons: ['#ng2ChangeDetectionJit'],
id: 'ng2.changeDetection.jit',
params: [{
name: 'numberOfChecks', value: 900000, scale: 'linear'
}] }]
}); });
}); });
@ -20,10 +31,10 @@ describe('ng2 change detection benchmark', function () {
it('should log baseline stats', function() { it('should log baseline stats', function() {
perfUtil.runClickBenchmark({ perfUtil.runClickBenchmark({
url: URL, url: URL,
buttons: ['#baselineDetectChanges'], buttons: ['#baselineChangeDetection'],
id: 'baseline.changeDetection', id: 'baseline.changeDetection',
params: [{ params: [{
name: 'iterations', value: 500000, scale: 'linear' name: 'numberOfChecks', value: 900000, scale: 'linear'
}] }]
}); });
}); });

View File

@ -5,15 +5,16 @@
<h2>Params</h2> <h2>Params</h2>
<form> <form>
Iterations: Iterations:
<input type="number" name="iterations" placeholder="iterations" value="500000"> <input type="number" name="numberOfChecks" placeholder="numberOfChecks" value="900000">
<br> <br>
<button>Apply</button> <button>Apply</button>
</form> </form>
<h2>Actions</h2> <h2>Actions</h2>
<p> <p>
<button id="ng2DetectChanges">Ng2 detect changes</button> <button id="ng2ChangeDetectionDynamic">Ng2 detect changes (dynamic)</button>
<button id="baselineDetectChanges">baselineDetectChanges</button> <button id="ng2ChangeDetectionJit">Ng2 detect changes (jit)</button>
<button id="baselineChangeDetection">baselineDetectChanges</button>
</p> </p>
$SCRIPTS$ $SCRIPTS$

View File

@ -1,15 +1,15 @@
import {ListWrapper, MapWrapper} from 'facade/src/collection'; import {ListWrapper, MapWrapper} from 'facade/src/collection';
import {reflector} from 'reflection/src/reflection'; import {reflector} from 'reflection/src/reflection';
import {isPresent} from 'facade/src/lang'; import {isPresent, isJsObject} from 'facade/src/lang';
import {getIntParameter, bindAction} from 'e2e_test_lib/src/benchmark_util'; import {getIntParameter, bindAction} from 'e2e_test_lib/src/benchmark_util';
import { import {
Lexer, Lexer,
Parser, Parser,
ChangeDetector,
ProtoChangeDetector,
DynamicProtoChangeDetector,
ChangeDispatcher, ChangeDispatcher,
ChangeDetection,
dynamicChangeDetection,
jitChangeDetection
} from 'change_detection/change_detection'; } from 'change_detection/change_detection';
@ -43,9 +43,8 @@ class Obj {
} }
class Row { class Row {
currentValue;
previousValue; previousValue;
obj;
getter;
next; next;
} }
@ -79,13 +78,13 @@ function setUpReflector() {
function setUpBaseline(iterations) { function setUpBaseline(iterations) {
function createRow(i) { function createRow(i) {
var obj = new Obj(); var obj = new Obj();
var index = i % 10; for (var j = 0; j < 10; ++j) {
obj.setField(index, i); obj.setField(j, i);
}
var r = new Row(); var r = new Row();
r.obj = obj; r.currentValue = obj;
r.previousValue = i; r.previousValue = obj;
r.getter = reflector.getter(`field${index}`);
return r; return r;
} }
@ -99,13 +98,14 @@ function setUpBaseline(iterations) {
return head; return head;
} }
function setUpChangeDetection(iterations) { function setUpChangeDetection(changeDetection:ChangeDetection, iterations) {
var dispatcher = new DummyDispatcher(); var dispatcher = new DummyDispatcher();
var parser = new Parser(new Lexer()); var parser = new Parser(new Lexer());
var parentProto = new DynamicProtoChangeDetector(); var parentProto = changeDetection.createProtoChangeDetector('parent');
var parentCD = parentProto.instantiate(dispatcher, MapWrapper.create()); var parentCd = parentProto.instantiate(dispatcher, MapWrapper.create());
var proto = changeDetection.createProtoChangeDetector("proto");
var astWithSource = [ var astWithSource = [
parser.parseBinding('field0', null), parser.parseBinding('field0', null),
parser.parseBinding('field1', null), parser.parseBinding('field1', null),
@ -118,63 +118,90 @@ function setUpChangeDetection(iterations) {
parser.parseBinding('field8', null), parser.parseBinding('field8', null),
parser.parseBinding('field9', null) parser.parseBinding('field9', null)
]; ];
for (var j = 0; j < 10; ++j) {
function proto(i) { proto.addAst(astWithSource[j].ast, "memo", j, false);
var pcd = new DynamicProtoChangeDetector();
pcd.addAst(astWithSource[i % 10].ast, "memo", i, false);
return pcd;
} }
var pcd = [
proto(0),
proto(1),
proto(2),
proto(3),
proto(4),
proto(5),
proto(6),
proto(7),
proto(8),
proto(9)
];
for (var i = 0; i < iterations; ++i) { for (var i = 0; i < iterations; ++i) {
var obj = new Obj(); var obj = new Obj();
var index = i % 10; for (var j = 0; j < 10; ++j) {
obj.setField(index, i); obj.setField(j, i);
var rr = pcd[index].instantiate(dispatcher, null);
rr.setContext(obj);
parentCD.addChild(rr);
} }
var cd = proto.instantiate(dispatcher, null);
return parentCD; cd.setContext(obj);
parentCd.addChild(cd);
}
return parentCd;
} }
export function main () { export function main () {
var iterations = getIntParameter('iterations'); var numberOfChecks = getIntParameter('numberOfChecks');
var numberOfChecksPerDetector = 10;
var numberOfRuns = 20;
var numberOfDetectors = numberOfChecks / numberOfChecksPerDetector / numberOfRuns;
setUpReflector(); setUpReflector();
var baselineHead = setUpBaseline(iterations);
var ng2ChangeDetector = setUpChangeDetection(iterations);
function baselineDetectChanges() { // -- BASELINE
function checkBaselineRow(r) {
var curr = r.currentValue;
var prev = r.previousValue;
if (curr.field0 !== prev.field0) throw "should not happen";
if (curr.field1 !== prev.field1) throw "should not happen";
if (curr.field2 !== prev.field2) throw "should not happen";
if (curr.field3 !== prev.field3) throw "should not happen";
if (curr.field4 !== prev.field4) throw "should not happen";
if (curr.field5 !== prev.field5) throw "should not happen";
if (curr.field6 !== prev.field6) throw "should not happen";
if (curr.field7 !== prev.field7) throw "should not happen";
if (curr.field8 !== prev.field8) throw "should not happen";
if (curr.field9 !== prev.field9) throw "should not happen";
}
var baselineHead = setUpBaseline(numberOfDetectors);
function runBaselineChangeDetection(){
var current = baselineHead; var current = baselineHead;
while (isPresent(current)) { while (isPresent(current)) {
if (current.getter(current.obj) !== current.previousValue) { checkBaselineRow(current);
throw "should not happen";
}
current = current.next; current = current.next;
} }
} }
function baselineChangeDetection() {
for (var i = 0; i < numberOfRuns; ++i) {
runBaselineChangeDetection();
}
}
runBaselineChangeDetection();
bindAction('#baselineChangeDetection', baselineChangeDetection);
function ng2DetectChanges() {
ng2ChangeDetector.detectChanges(); // -- DYNAMIC
var ng2DynamicChangeDetector = setUpChangeDetection(dynamicChangeDetection, numberOfDetectors);
function ng2ChangeDetectionDynamic() {
for(var i = 0; i < numberOfRuns; ++i) {
ng2DynamicChangeDetector.detectChanges();
}
}
ng2DynamicChangeDetector.detectChanges();
bindAction('#ng2ChangeDetectionDynamic', ng2ChangeDetectionDynamic);
// -- JIT
// Reenable when we have transformers for Dart
if (isJsObject({})) {
var ng2JitChangeDetector = setUpChangeDetection(jitChangeDetection, numberOfDetectors);
function ng2ChangeDetectionJit() {
for (var i = 0; i < numberOfRuns; ++i) {
ng2JitChangeDetector.detectChanges();
}
} }
bindAction('#ng2DetectChanges', ng2DetectChanges); ng2JitChangeDetector.detectChanges();
bindAction('#baselineDetectChanges', baselineDetectChanges); bindAction('#ng2ChangeDetectionJit', ng2ChangeDetectionJit);
} else {
bindAction('#ng2ChangeDetectionJit', () => {});
}
} }