feat(change_detection): update change detection benchmark
This commit is contained in:
parent
709df12b10
commit
3067601961
|
@ -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'
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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$
|
||||||
|
|
|
@ -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);
|
var cd = proto.instantiate(dispatcher, null);
|
||||||
rr.setContext(obj);
|
cd.setContext(obj);
|
||||||
|
parentCd.addChild(cd);
|
||||||
parentCD.addChild(rr);
|
|
||||||
}
|
}
|
||||||
|
return parentCd;
|
||||||
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() {
|
||||||
function ng2DetectChanges() {
|
for (var i = 0; i < numberOfRuns; ++i) {
|
||||||
ng2ChangeDetector.detectChanges();
|
runBaselineChangeDetection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
runBaselineChangeDetection();
|
||||||
|
bindAction('#baselineChangeDetection', baselineChangeDetection);
|
||||||
|
|
||||||
bindAction('#ng2DetectChanges', ng2DetectChanges);
|
|
||||||
bindAction('#baselineDetectChanges', baselineDetectChanges);
|
// -- 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ng2JitChangeDetector.detectChanges();
|
||||||
|
bindAction('#ng2ChangeDetectionJit', ng2ChangeDetectionJit);
|
||||||
|
} else {
|
||||||
|
bindAction('#ng2ChangeDetectionJit', () => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue