2015-02-02 16:25:34 -08:00
|
|
|
import {ListWrapper, MapWrapper} from 'facade/src/collection';
|
|
|
|
|
import {reflector} from 'reflection/src/reflection';
|
|
|
|
|
import {isPresent} from 'facade/src/lang';
|
|
|
|
|
import {getIntParameter, bindAction} from 'e2e_test_lib/src/benchmark_util';
|
2014-11-14 16:51:55 -08:00
|
|
|
|
|
|
|
|
import {
|
2014-12-29 09:51:52 -08:00
|
|
|
Lexer,
|
|
|
|
|
Parser,
|
2014-11-14 16:51:55 -08:00
|
|
|
ChangeDetector,
|
2015-01-14 13:51:16 -08:00
|
|
|
ProtoChangeDetector,
|
2015-01-21 12:05:52 -08:00
|
|
|
DynamicProtoChangeDetector,
|
2014-12-04 13:16:38 +01:00
|
|
|
ChangeDispatcher,
|
2014-12-29 09:51:52 -08:00
|
|
|
} from 'change_detection/change_detection';
|
2014-11-14 16:51:55 -08:00
|
|
|
|
|
|
|
|
|
2014-12-03 11:26:39 -08:00
|
|
|
class Obj {
|
|
|
|
|
field0;
|
|
|
|
|
field1;
|
|
|
|
|
field2;
|
|
|
|
|
field3;
|
|
|
|
|
field4;
|
|
|
|
|
field5;
|
|
|
|
|
field6;
|
|
|
|
|
field7;
|
|
|
|
|
field8;
|
|
|
|
|
field9;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setField(index, value) {
|
|
|
|
|
switch (index) {
|
|
|
|
|
case 0: this.field0 = value; break;
|
|
|
|
|
case 1: this.field1 = value; break;
|
|
|
|
|
case 2: this.field2 = value; break;
|
|
|
|
|
case 3: this.field3 = value; break;
|
|
|
|
|
case 4: this.field4 = value; break;
|
|
|
|
|
case 5: this.field5 = value; break;
|
|
|
|
|
case 6: this.field6 = value; break;
|
|
|
|
|
case 7: this.field7 = value; break;
|
|
|
|
|
case 8: this.field8 = value; break;
|
|
|
|
|
case 9: this.field9 = value; break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Row {
|
|
|
|
|
previousValue;
|
|
|
|
|
obj;
|
|
|
|
|
getter;
|
|
|
|
|
next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setUpReflector() {
|
2014-11-14 16:51:55 -08:00
|
|
|
reflector.registerGetters({
|
2014-12-03 11:26:39 -08:00
|
|
|
'field0': function(obj){return obj.field0},
|
|
|
|
|
'field1': function(obj){return obj.field1},
|
|
|
|
|
'field2': function(obj){return obj.field2},
|
|
|
|
|
'field3': function(obj){return obj.field3},
|
|
|
|
|
'field4': function(obj){return obj.field4},
|
|
|
|
|
'field5': function(obj){return obj.field5},
|
|
|
|
|
'field6': function(obj){return obj.field6},
|
|
|
|
|
'field7': function(obj){return obj.field7},
|
|
|
|
|
'field8': function(obj){return obj.field8},
|
|
|
|
|
'field9': function(obj){return obj.field9}
|
2014-11-14 16:51:55 -08:00
|
|
|
});
|
|
|
|
|
reflector.registerSetters({
|
2014-12-03 11:26:39 -08:00
|
|
|
'field0': function(obj, v){return obj.field0 = v},
|
|
|
|
|
'field1': function(obj, v){return obj.field1 = v},
|
|
|
|
|
'field2': function(obj, v){return obj.field2 = v},
|
|
|
|
|
'field3': function(obj, v){return obj.field3 = v},
|
|
|
|
|
'field4': function(obj, v){return obj.field4 = v},
|
|
|
|
|
'field5': function(obj, v){return obj.field5 = v},
|
|
|
|
|
'field6': function(obj, v){return obj.field6 = v},
|
|
|
|
|
'field7': function(obj, v){return obj.field7 = v},
|
|
|
|
|
'field8': function(obj, v){return obj.field8 = v},
|
|
|
|
|
'field9': function(obj, v){return obj.field9 = v}
|
2014-11-14 16:51:55 -08:00
|
|
|
});
|
2014-12-03 11:26:39 -08:00
|
|
|
}
|
2014-11-14 16:51:55 -08:00
|
|
|
|
2015-01-09 18:00:04 -08:00
|
|
|
function setUpBaseline(iterations) {
|
2014-12-03 11:26:39 -08:00
|
|
|
function createRow(i) {
|
|
|
|
|
var obj = new Obj();
|
|
|
|
|
var index = i % 10;
|
|
|
|
|
obj.setField(index, i);
|
2014-11-14 16:51:55 -08:00
|
|
|
|
2014-12-03 11:26:39 -08:00
|
|
|
var r = new Row();
|
|
|
|
|
r.obj = obj;
|
|
|
|
|
r.previousValue = i;
|
|
|
|
|
r.getter = reflector.getter(`field${index}`);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
2014-11-14 16:51:55 -08:00
|
|
|
|
2014-12-03 11:26:39 -08:00
|
|
|
var head = createRow(0);
|
|
|
|
|
var current = head;
|
2015-01-09 18:00:04 -08:00
|
|
|
for (var i = 1; i < iterations; i++) {
|
2014-12-03 11:26:39 -08:00
|
|
|
var newRow = createRow(i);
|
|
|
|
|
current.next = newRow;
|
|
|
|
|
current = newRow;
|
|
|
|
|
}
|
|
|
|
|
return head;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-09 18:00:04 -08:00
|
|
|
function setUpChangeDetection(iterations) {
|
2014-11-14 16:51:55 -08:00
|
|
|
var dispatcher = new DummyDispatcher();
|
2014-12-03 11:26:39 -08:00
|
|
|
var parser = new Parser(new Lexer());
|
|
|
|
|
|
2015-01-21 12:05:52 -08:00
|
|
|
var parentProto = new DynamicProtoChangeDetector();
|
2015-01-14 13:51:16 -08:00
|
|
|
var parentCD = parentProto.instantiate(dispatcher, MapWrapper.create());
|
2014-12-03 11:26:39 -08:00
|
|
|
|
|
|
|
|
var astWithSource = [
|
2014-12-10 19:21:15 -08:00
|
|
|
parser.parseBinding('field0', null),
|
|
|
|
|
parser.parseBinding('field1', null),
|
|
|
|
|
parser.parseBinding('field2', null),
|
|
|
|
|
parser.parseBinding('field3', null),
|
|
|
|
|
parser.parseBinding('field4', null),
|
|
|
|
|
parser.parseBinding('field5', null),
|
|
|
|
|
parser.parseBinding('field6', null),
|
|
|
|
|
parser.parseBinding('field7', null),
|
|
|
|
|
parser.parseBinding('field8', null),
|
|
|
|
|
parser.parseBinding('field9', null)
|
2014-12-03 11:26:39 -08:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
function proto(i) {
|
2015-01-21 12:05:52 -08:00
|
|
|
var pcd = new DynamicProtoChangeDetector();
|
2015-01-14 13:51:16 -08:00
|
|
|
pcd.addAst(astWithSource[i % 10].ast, "memo", i, false);
|
|
|
|
|
return pcd;
|
2014-12-03 11:26:39 -08:00
|
|
|
}
|
|
|
|
|
|
2015-01-14 13:51:16 -08:00
|
|
|
var pcd = [
|
2014-12-03 11:26:39 -08:00
|
|
|
proto(0),
|
|
|
|
|
proto(1),
|
|
|
|
|
proto(2),
|
|
|
|
|
proto(3),
|
|
|
|
|
proto(4),
|
|
|
|
|
proto(5),
|
|
|
|
|
proto(6),
|
|
|
|
|
proto(7),
|
|
|
|
|
proto(8),
|
|
|
|
|
proto(9)
|
|
|
|
|
];
|
2014-11-14 16:51:55 -08:00
|
|
|
|
2015-01-09 18:00:04 -08:00
|
|
|
for (var i = 0; i < iterations; ++i) {
|
2014-12-03 11:26:39 -08:00
|
|
|
var obj = new Obj();
|
|
|
|
|
var index = i % 10;
|
|
|
|
|
obj.setField(index, i);
|
|
|
|
|
|
2015-01-14 13:51:16 -08:00
|
|
|
var rr = pcd[index].instantiate(dispatcher, null);
|
2014-12-03 11:26:39 -08:00
|
|
|
rr.setContext(obj);
|
|
|
|
|
|
2015-01-14 13:51:16 -08:00
|
|
|
parentCD.addChild(rr);
|
2014-11-14 16:51:55 -08:00
|
|
|
}
|
2014-12-03 11:26:39 -08:00
|
|
|
|
2015-01-14 13:51:16 -08:00
|
|
|
return parentCD;
|
2014-11-14 16:51:55 -08:00
|
|
|
}
|
|
|
|
|
|
2014-12-05 16:26:30 -08:00
|
|
|
export function main () {
|
2015-01-09 18:00:04 -08:00
|
|
|
var iterations = getIntParameter('iterations');
|
|
|
|
|
|
2014-12-03 11:26:39 -08:00
|
|
|
setUpReflector();
|
2015-01-09 18:00:04 -08:00
|
|
|
var baselineHead = setUpBaseline(iterations);
|
|
|
|
|
var ng2ChangeDetector = setUpChangeDetection(iterations);
|
2014-12-22 17:50:10 -08:00
|
|
|
|
2015-01-09 18:00:04 -08:00
|
|
|
function baselineDetectChanges() {
|
2014-12-22 17:50:10 -08:00
|
|
|
var current = baselineHead;
|
|
|
|
|
while (isPresent(current)) {
|
|
|
|
|
if (current.getter(current.obj) !== current.previousValue) {
|
|
|
|
|
throw "should not happen";
|
2014-12-03 11:26:39 -08:00
|
|
|
}
|
2014-12-22 17:50:10 -08:00
|
|
|
current = current.next;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-03 11:26:39 -08:00
|
|
|
|
2015-01-09 18:00:04 -08:00
|
|
|
function ng2DetectChanges() {
|
2014-12-22 17:50:10 -08:00
|
|
|
ng2ChangeDetector.detectChanges();
|
|
|
|
|
}
|
2014-12-03 11:26:39 -08:00
|
|
|
|
2015-01-09 18:00:04 -08:00
|
|
|
bindAction('#ng2DetectChanges', ng2DetectChanges);
|
|
|
|
|
bindAction('#baselineDetectChanges', baselineDetectChanges);
|
2014-11-14 16:51:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-12-04 13:16:38 +01:00
|
|
|
class DummyDispatcher extends ChangeDispatcher {
|
2014-12-03 11:26:39 -08:00
|
|
|
onRecordChange(record, context) {
|
2014-11-14 16:51:55 -08:00
|
|
|
}
|
2014-12-04 13:16:38 +01:00
|
|
|
}
|