@@ -2,6 +2,8 @@ import {ListWrapper, MapWrapper} from 'facade/collection';
22import { Parser } from 'change_detection/parser/parser' ;
33import { Lexer } from 'change_detection/parser/lexer' ;
44import { reflector } from 'reflection/reflection' ;
5+ import { isPresent } from 'facade/lang' ;
6+ import { benchmark , benchmarkStep } from '../benchpress' ;
57
68import {
79 ChangeDetector ,
@@ -10,51 +12,175 @@ import {
1012} from 'change_detection/change_detector' ;
1113
1214
13- var ITERATIONS = 100000 ;
15+ var ITERATIONS = 200000 ;
1416
15- export function run ( ) {
17+ class Obj {
18+ field0 ;
19+ field1 ;
20+ field2 ;
21+ field3 ;
22+ field4 ;
23+ field5 ;
24+ field6 ;
25+ field7 ;
26+ field8 ;
27+ field9 ;
28+
29+
30+ setField ( index , value ) {
31+ switch ( index ) {
32+ case 0 : this . field0 = value ; break ;
33+ case 1 : this . field1 = value ; break ;
34+ case 2 : this . field2 = value ; break ;
35+ case 3 : this . field3 = value ; break ;
36+ case 4 : this . field4 = value ; break ;
37+ case 5 : this . field5 = value ; break ;
38+ case 6 : this . field6 = value ; break ;
39+ case 7 : this . field7 = value ; break ;
40+ case 8 : this . field8 = value ; break ;
41+ case 9 : this . field9 = value ; break ;
42+ }
43+ }
44+ }
45+
46+ class Row {
47+ previousValue ;
48+ obj ;
49+ getter ;
50+ next ;
51+ }
52+
53+ function setUpReflector ( ) {
1654 reflector . registerGetters ( {
17- 'a' : function ( obj ) { return obj . a } ,
18- 'b' : function ( obj ) { return obj . b } ,
19- 'c' : function ( obj ) { return obj . c }
55+ 'field0' : function ( obj ) { return obj . field0 } ,
56+ 'field1' : function ( obj ) { return obj . field1 } ,
57+ 'field2' : function ( obj ) { return obj . field2 } ,
58+ 'field3' : function ( obj ) { return obj . field3 } ,
59+ 'field4' : function ( obj ) { return obj . field4 } ,
60+ 'field5' : function ( obj ) { return obj . field5 } ,
61+ 'field6' : function ( obj ) { return obj . field6 } ,
62+ 'field7' : function ( obj ) { return obj . field7 } ,
63+ 'field8' : function ( obj ) { return obj . field8 } ,
64+ 'field9' : function ( obj ) { return obj . field9 }
2065 } ) ;
21-
2266 reflector . registerSetters ( {
23- 'a' : function ( obj , v ) { return obj . a = v } ,
24- 'b' : function ( obj , v ) { return obj . b = v } ,
25- 'c' : function ( obj , v ) { return obj . c = v }
67+ 'field0' : function ( obj , v ) { return obj . field0 = v } ,
68+ 'field1' : function ( obj , v ) { return obj . field1 = v } ,
69+ 'field2' : function ( obj , v ) { return obj . field2 = v } ,
70+ 'field3' : function ( obj , v ) { return obj . field3 = v } ,
71+ 'field4' : function ( obj , v ) { return obj . field4 = v } ,
72+ 'field5' : function ( obj , v ) { return obj . field5 = v } ,
73+ 'field6' : function ( obj , v ) { return obj . field6 = v } ,
74+ 'field7' : function ( obj , v ) { return obj . field7 = v } ,
75+ 'field8' : function ( obj , v ) { return obj . field8 = v } ,
76+ 'field9' : function ( obj , v ) { return obj . field9 = v }
2677 } ) ;
78+ }
2779
28- var parser = new Parser ( new Lexer ( ) ) ;
29- var astWithSource = parser . parseBinding ( 'a + b * c' ) ;
80+ function setUpBaseline ( ) {
81+ function createRow ( i ) {
82+ var obj = new Obj ( ) ;
83+ var index = i % 10 ;
84+ obj . setField ( index , i ) ;
3085
31- var prr = new ProtoRecordRange ( ) ;
32- prr . addRecordsFromAST ( astWithSource . ast , 'memo' , false ) ;
86+ var r = new Row ( ) ;
87+ r . obj = obj ;
88+ r . previousValue = i ;
89+ r . getter = reflector . getter ( `field${ index } ` ) ;
90+ return r ;
91+ }
3392
93+ var head = createRow ( 0 ) ;
94+ var current = head ;
95+ for ( var i = 1 ; i < ITERATIONS ; i ++ ) {
96+ var newRow = createRow ( i ) ;
97+ current . next = newRow ;
98+ current = newRow ;
99+ }
100+ return head ;
101+ }
102+
103+ function setUpChangeDetection ( ) {
34104 var dispatcher = new DummyDispatcher ( ) ;
35- var rr = prr . instantiate ( dispatcher , MapWrapper . create ( ) ) ;
36- rr . setContext ( new Component ( ) ) ;
105+ var parser = new Parser ( new Lexer ( ) ) ;
106+
107+ var parentProto = new ProtoRecordRange ( ) ;
108+ var parentRange = parentProto . instantiate ( dispatcher , MapWrapper . create ( ) ) ;
109+
110+ var astWithSource = [
111+ parser . parseBinding ( 'field0' ) ,
112+ parser . parseBinding ( 'field1' ) ,
113+ parser . parseBinding ( 'field2' ) ,
114+ parser . parseBinding ( 'field3' ) ,
115+ parser . parseBinding ( 'field4' ) ,
116+ parser . parseBinding ( 'field5' ) ,
117+ parser . parseBinding ( 'field6' ) ,
118+ parser . parseBinding ( 'field7' ) ,
119+ parser . parseBinding ( 'field8' ) ,
120+ parser . parseBinding ( 'field9' )
121+ ] ;
122+
123+ function proto ( i ) {
124+ var prr = new ProtoRecordRange ( ) ;
125+ prr . addRecordsFromAST ( astWithSource [ i % 10 ] . ast , "memo" , i , false ) ;
126+ return prr ;
127+ }
128+
129+ var prr = [
130+ proto ( 0 ) ,
131+ proto ( 1 ) ,
132+ proto ( 2 ) ,
133+ proto ( 3 ) ,
134+ proto ( 4 ) ,
135+ proto ( 5 ) ,
136+ proto ( 6 ) ,
137+ proto ( 7 ) ,
138+ proto ( 8 ) ,
139+ proto ( 9 )
140+ ] ;
37141
38- var cd = new ChangeDetector ( rr ) ;
39142 for ( var i = 0 ; i < ITERATIONS ; ++ i ) {
40- cd . detectChanges ( ) ;
143+ var obj = new Obj ( ) ;
144+ var index = i % 10 ;
145+ obj . setField ( index , i ) ;
146+
147+ var rr = prr [ index ] . instantiate ( dispatcher , null ) ;
148+ rr . setContext ( obj ) ;
149+
150+ parentRange . addRange ( rr ) ;
41151 }
152+
153+ return new ChangeDetector ( parentRange ) ;
42154}
43155
156+ export function run ( ) {
157+ setUpReflector ( ) ;
44158
45- class DummyDispatcher extends WatchGroupDispatcher {
46- onRecordChange ( record , context ) {
47- }
159+ benchmark ( `Baseline` , function ( ) {
160+ var head = setUpBaseline ( ) ;
161+
162+ benchmarkStep ( 'run' , function ( ) {
163+ var current = head ;
164+ while ( isPresent ( current ) ) {
165+ if ( current . getter ( current . obj ) !== current . previousValue ) {
166+ throw "should not happen" ;
167+ }
168+ current = current . next ;
169+ }
170+ } ) ;
171+ } ) ;
172+
173+ benchmark ( `Change Detection` , function ( ) {
174+ var cd = setUpChangeDetection ( ) ;
175+
176+ benchmarkStep ( 'run' , function ( ) {
177+ cd . detectChanges ( ) ;
178+ } ) ;
179+ } ) ;
48180}
49181
50- class Component {
51- a :number ;
52- b :number ;
53- c :number ;
54182
55- constructor ( ) {
56- this . a = 1 ;
57- this . b = 2 ;
58- this . c = 3 ;
183+ class DummyDispatcher extends WatchGroupDispatcher {
184+ onRecordChange ( record , context ) {
59185 }
60186}
0 commit comments