Skip to content

Commit 10b09df

Browse files
jbedardIgorMinar
authored andcommitted
test($parse): adding benchmark for execution of $parse()ed expressions
Part of angular#8901
1 parent 6046e14 commit 10b09df

File tree

3 files changed

+287
-0
lines changed

3 files changed

+287
-0
lines changed
+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
var app = angular.module('parsedExpressionBenchmark', []);
2+
3+
app.config(function($compileProvider) {
4+
if ($compileProvider.debugInfoEnabled) {
5+
$compileProvider.debugInfoEnabled(false);
6+
}
7+
});
8+
9+
app.filter('noop', function() {
10+
return function(input) {
11+
return input;
12+
};
13+
});
14+
15+
//Executes the specified expression as a watcher
16+
app.directive('bmPeWatch', function() {
17+
return {
18+
restrict: 'A',
19+
compile: function($element, $attrs) {
20+
$element.text( $attrs.bmPeWatch );
21+
return function($scope, $element, $attrs) {
22+
$scope.$watch($attrs.bmPeWatch, function(val) {
23+
$element.text(val);
24+
25+
});
26+
};
27+
}
28+
};
29+
});
30+
31+
//Executes the specified expression as a watcher
32+
//Adds a simple wrapper method to allow use of $watch instead of $watchCollection
33+
app.directive('bmPeWatchLiteral', function($parse) {
34+
function retZero() {
35+
return 0;
36+
}
37+
38+
return {
39+
restrict: 'A',
40+
compile: function($element, $attrs) {
41+
$element.text( $attrs.bmPeWatchLiteral );
42+
return function($scope, $element, $attrs) {
43+
$scope.$watch( $parse($attrs.bmPeWatchLiteral, retZero) );
44+
};
45+
}
46+
};
47+
});
48+
49+
app.controller('DataController', function($scope, $rootScope) {
50+
var totalRows = 10000;
51+
52+
var data = $scope.data = [];
53+
54+
var star = '*';
55+
56+
$scope.func = function() { return star;};
57+
58+
for (var i=0; i<totalRows; i++) {
59+
data.push({
60+
index: i,
61+
odd: i%2 === 0,
62+
even: i%2 === 1,
63+
str0: "foo-" + Math.random()*Date.now(),
64+
str1: "bar-" + Math.random()*Date.now(),
65+
str2: "baz-" + Math.random()*Date.now(),
66+
num0: Math.random()*Date.now(),
67+
num1: Math.random()*Date.now(),
68+
num2: Math.random()*Date.now(),
69+
date0: new Date(Math.random()*Date.now()),
70+
date1: new Date(Math.random()*Date.now()),
71+
date2: new Date(Math.random()*Date.now()),
72+
func: function(){ return star; },
73+
obj: data[i-1],
74+
keys: data[i-1] && (data[i-1].keys || Object.keys(data[i-1]))
75+
});
76+
}
77+
78+
benchmarkSteps.push({
79+
name: '$apply',
80+
fn: function() {
81+
for (var i=0; i<50; i++) {
82+
$rootScope.$digest();
83+
}
84+
}
85+
});
86+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = function(config) {
2+
config.set({
3+
scripts: [ {
4+
id: 'angular',
5+
src: '/build/angular.js'
6+
},
7+
{
8+
src: 'app.js',
9+
}]
10+
});
11+
};
+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
<div ng-app="parsedExpressionBenchmark" ng-cloak>
2+
<div ng-controller="DataController">
3+
<div class="container-fluid">
4+
<p>
5+
Tests the execution of $parse()ed expressions. Each test tries to isolate specific expression types. Expressions should (probably) not be constant so they get evaluated per digest.
6+
</p>
7+
8+
<ul style="list-style:none">
9+
<li>
10+
<input type="radio" ng-model="expressionType" value="simpleProperty" id="simpleProperty">
11+
<label for="simpleProperty">Simple Properties</label>
12+
</li>
13+
14+
<li>
15+
<input type="radio" ng-model="expressionType" value="fieldAccess" id="fieldAccess">
16+
<label for="fieldAccess">Field Accessors</label>
17+
</li>
18+
19+
<li>
20+
<input type="radio" ng-model="expressionType" value="fieldIndex" id="fieldIndex">
21+
<label for="fieldIndex">Field Indexors</label>
22+
</li>
23+
24+
<li>
25+
<input type="radio" ng-model="expressionType" value="operators" id="operators">
26+
<label for="operators">Binary/Unary operators</label>
27+
</li>
28+
29+
<li>
30+
<input type="radio" ng-model="expressionType" value="filters" id="filters">
31+
<label for="filters">Filters</label>
32+
</li>
33+
34+
<li>
35+
<input type="radio" ng-model="expressionType" value="functionCalls" id="functionCalls">
36+
<label for="functionCalls">Function calls</label>
37+
</li>
38+
39+
<li>
40+
<input type="radio" ng-model="expressionType" value="objectLiterals" id="objectLiterals">
41+
<label for="objectLiterals">Object Literals</label>
42+
</li>
43+
44+
<li>
45+
<input type="radio" ng-model="expressionType" value="arrayLiterals" id="arrayLiterals">
46+
<label for="arrayLiterals">Array Literals</label>
47+
</li>
48+
</ul>
49+
50+
<!--
51+
NOTES:
52+
- ensure each tested expression has at least one variable in it to avoid constant expressions
53+
-->
54+
55+
<ul ng-switch="expressionType">
56+
<li ng-switch-when="simpleProperty" ng-repeat="(rowIdx, row) in ::data">
57+
<span bm-pe-watch="rowIdx"></span>
58+
<span bm-pe-watch="row.index"></span>
59+
<span bm-pe-watch="row.num0"></span>
60+
<span bm-pe-watch="row.num1"></span>
61+
<span bm-pe-watch="row.num2"></span>
62+
<span bm-pe-watch="row.str0"></span>
63+
<span bm-pe-watch="row.str1"></span>
64+
<span bm-pe-watch="row.str2"></span>
65+
<span bm-pe-watch="row.date0"></span>
66+
<span bm-pe-watch="row.obj"></span>
67+
<span bm-pe-watch="row.keys"></span>
68+
</li>
69+
70+
<li ng-switch-when="fieldAccess" ng-repeat="(rowIdx, row) in ::data">
71+
<span bm-pe-watch="row.index"></span>
72+
<span bm-pe-watch="row.num0"></span>
73+
<span bm-pe-watch="row.num1"></span>
74+
<span bm-pe-watch="row.str0"></span>
75+
<span bm-pe-watch="row.str1"></span>
76+
<span bm-pe-watch="row.obj.index"></span>
77+
<span bm-pe-watch="row.obj.index"></span>
78+
<span bm-pe-watch="row.obj.index"></span>
79+
<span bm-pe-watch="row.obj.obj.index"></span>
80+
<span bm-pe-watch="row.obj.obj.index"></span>
81+
<span bm-pe-watch="row.obj.obj.obj.index"></span>
82+
<span bm-pe-watch="row.obj.obj.obj.index"></span>
83+
</li>
84+
85+
<li ng-switch-when="fieldIndex" ng-repeat="(rowIdx, row) in ::data">
86+
<span bm-pe-watch="data[rowIdx]"></span>
87+
<span bm-pe-watch="row['str0']"></span>
88+
<span bm-pe-watch="row['str1']"></span>
89+
<span bm-pe-watch="data[row['index']]['index']"></span>
90+
<span bm-pe-watch="data[rowIdx]['obj']"></span>
91+
<span bm-pe-watch="data[rowIdx]['obj']['obj']"></span>
92+
<span bm-pe-watch="row[row['keys'][0]]"></span>
93+
<span bm-pe-watch="row[row['keys'][1]]"></span>
94+
<span bm-pe-watch="row[row['keys'][2]]"></span>
95+
<span bm-pe-watch="row[row['keys'][3]]"></span>
96+
<span bm-pe-watch="row[row['keys'][4]]"></span>
97+
<span bm-pe-watch="row[row['keys'][5]]"></span>
98+
99+
</li>
100+
101+
<li ng-switch-when="operators" ng-repeat="(rowIdx, row) in ::data">
102+
<span bm-pe-watch="+rowIdx"></span>
103+
<span bm-pe-watch="-rowIdx"></span>
104+
<span bm-pe-watch="rowIdx + 1"></span>
105+
<span bm-pe-watch="rowIdx - 1"></span>
106+
<span bm-pe-watch="rowIdx * 2"></span>
107+
<span bm-pe-watch="rowIdx + -1"></span>
108+
<span bm-pe-watch="rowIdx - -1"></span>
109+
<span bm-pe-watch="-rowIdx * 2 + 1"></span>
110+
<span bm-pe-watch="rowIdx % 2"></span>
111+
<span bm-pe-watch="rowIdx % 2 === 1"></span>
112+
<span bm-pe-watch="rowIdx % 2 === 0"></span>
113+
<span bm-pe-watch="rowIdx / 1"></span>
114+
<span bm-pe-watch="-rowIdx * 2 * rowIdx + rowIdx / rowIdx + 1"></span>
115+
</li>
116+
117+
<li ng-switch-when="filters" ng-repeat="(rowIdx, row) in ::data">
118+
<span bm-pe-watch="rowIdx | noop"></span>
119+
<span bm-pe-watch="rowIdx | noop"></span>
120+
<span bm-pe-watch="rowIdx | noop"></span>
121+
<span bm-pe-watch="rowIdx | noop:1"></span>
122+
<span bm-pe-watch="rowIdx | noop:rowIdx"></span>
123+
<span bm-pe-watch="rowIdx | noop:1:2:3:4:5"></span>
124+
<span bm-pe-watch="rowIdx | noop:rowIdx:rowIdx:rowIdx"></span>
125+
<span bm-pe-watch="rowIdx | noop | noop"></span>
126+
<span bm-pe-watch="rowIdx | noop:1 | noop"></span>
127+
<span bm-pe-watch="rowIdx | noop | noop:null:undefined:0"></span>
128+
<span bm-pe-watch="rowIdx | noop | noop | noop"></span>
129+
<span bm-pe-watch="rowIdx | noop:1 | noop:2 | noop:3"></span>
130+
</li>
131+
132+
<li ng-switch-when="functionCalls" ng-repeat="(rowIdx, row) in ::data">
133+
<span bm-pe-watch="func()"></span>
134+
<span bm-pe-watch="func(1)"></span>
135+
<span bm-pe-watch="func(1, 2)"></span>
136+
<span bm-pe-watch="func(1, 2, 3)"></span>
137+
<span bm-pe-watch="row.func()"></span>
138+
<span bm-pe-watch="row.func(1)"></span>
139+
<span bm-pe-watch="row.func(1, 2)"></span>
140+
<span bm-pe-watch="row.func(1, 2, 3)"></span>
141+
<span bm-pe-watch="func(func())"></span>
142+
<span bm-pe-watch="func(func(), func())"></span>
143+
<span bm-pe-watch="row.func(row.func())"></span>
144+
<span bm-pe-watch="row.func(row.func(), row.func())"></span>
145+
</li>
146+
147+
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
148+
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
149+
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
150+
<span bm-pe-watch-literal="{0: row, 1: rowIdx, 2: 3}"></span>
151+
<span bm-pe-watch-literal="{str: 'foo', num: rowIdx, b: true}"></span>
152+
<span bm-pe-watch-literal="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
153+
<span bm-pe-watch-literal="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
154+
</li>
155+
156+
<li ng-switch-when="arrayLiterals" ng-repeat="(rowIdx, row) in ::data">
157+
<span bm-pe-watch-literal="[rowIdx]"></span>
158+
<span bm-pe-watch-literal="[rowIdx, 0]"></span>
159+
<span bm-pe-watch-literal="[rowIdx, 0, 1]"></span>
160+
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2]"></span>
161+
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2, 3]"></span>
162+
<span bm-pe-watch-literal="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
163+
<span bm-pe-watch-literal="[rowIdx, undefined, null, true, false]"></span>
164+
<span bm-pe-watch-literal="[[][0], [0][0], [][rowIdx]]"></span>
165+
<span bm-pe-watch-literal="[0, rowIdx]"></span>
166+
<span bm-pe-watch-literal="[0, 1, rowIdx]"></span>
167+
<span bm-pe-watch-literal="[0, 1, 2, rowIdx]"></span>
168+
<span bm-pe-watch-literal="[0, 1, 2, 3, rowIdx]"></span>
169+
</li>
170+
171+
<!--
172+
<li ng-switch-when="" ng-repeat="(rowIdx, row) in data">
173+
<span bm-pe-watch=""></span>
174+
<span bm-pe-watch=""></span>
175+
<span bm-pe-watch=""></span>
176+
<span bm-pe-watch=""></span>
177+
<span bm-pe-watch=""></span>
178+
<span bm-pe-watch=""></span>
179+
<span bm-pe-watch=""></span>
180+
<span bm-pe-watch=""></span>
181+
<span bm-pe-watch=""></span>
182+
<span bm-pe-watch=""></span>
183+
<span bm-pe-watch=""></span>
184+
<span bm-pe-watch=""></span>
185+
</li>
186+
-->
187+
</ul>
188+
</div>
189+
</div>
190+
</div>

0 commit comments

Comments
 (0)