Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit fd45e8a

Browse files
committed
test($parse): adding benchmark for execution of $parse()ed expressions
1 parent eb47e91 commit fd45e8a

File tree

3 files changed

+284
-0
lines changed

3 files changed

+284
-0
lines changed
+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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);
23+
};
24+
}
25+
};
26+
});
27+
28+
//Executes the specified expression as a watcher
29+
//Adds a simple wrapper method to allow use of $watch instead of $watchCollection
30+
app.directive('bmPeWatchLiteral', function($parse) {
31+
function retZero() {
32+
return 0;
33+
}
34+
35+
return {
36+
restrict: 'A',
37+
compile: function($element, $attrs) {
38+
$element.text( $attrs.bmPeWatchLiteral );
39+
return function($scope, $element, $attrs) {
40+
$scope.$watch( $parse($attrs.bmPeWatchLiteral, retZero) );
41+
};
42+
}
43+
};
44+
});
45+
46+
app.controller('DataController', function($scope, $rootScope) {
47+
var totalRows = 2000;
48+
49+
var data = $scope.data = [];
50+
51+
$scope.func = function() {};
52+
53+
for (var i=0; i<totalRows; i++) {
54+
data.push({
55+
index: i,
56+
odd: i%2 === 0,
57+
even: i%2 === 1,
58+
str0: "foo-" + Math.random()*Date.now(),
59+
str1: "bar-" + Math.random()*Date.now(),
60+
str2: "baz-" + Math.random()*Date.now(),
61+
num0: Math.random()*Date.now(),
62+
num1: Math.random()*Date.now(),
63+
num2: Math.random()*Date.now(),
64+
date0: new Date(Math.random()*Date.now()),
65+
date1: new Date(Math.random()*Date.now()),
66+
date2: new Date(Math.random()*Date.now()),
67+
func: function(){},
68+
obj: data[i-1],
69+
keys: data[i-1] && (data[i-1].keys || Object.keys(data[i-1]))
70+
});
71+
}
72+
73+
benchmarkSteps.push({
74+
name: '$apply',
75+
fn: function() {
76+
for (var i=0; i<50; i++) {
77+
$rootScope.$digest();
78+
}
79+
}
80+
});
81+
});
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+
};
+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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.str0"></span>
62+
<span bm-pe-watch="row.str1"></span>
63+
<span bm-pe-watch="row.obj"></span>
64+
<span bm-pe-watch="row.obj.obj"></span>
65+
<span bm-pe-watch="row.obj.obj.obj"></span>
66+
<span bm-pe-watch="row.obj.obj.obj.obj"></span>
67+
<span bm-pe-watch="row.obj.obj.obj.obj.obj"></span>
68+
<span bm-pe-watch="row.obj.obj.obj.obj.obj.obj"></span>
69+
</li>
70+
71+
<li ng-switch-when="fieldAccess" ng-repeat="(rowIdx, row) in data">
72+
<span bm-pe-watch="row .index"></span>
73+
<span bm-pe-watch="row .obj . index"></span>
74+
<span bm-pe-watch="row.obj .index"></span>
75+
<span bm-pe-watch="row .obj .index"></span>
76+
<span bm-pe-watch="row .obj.obj .index"></span>
77+
<span bm-pe-watch="row .obj.obj .obj .index"></span>
78+
<span bm-pe-watch="row .obj .obj .index"></span>
79+
<span bm-pe-watch="row .obj .obj.obj .index"></span>
80+
<span bm-pe-watch="row .obj .obj .obj.index"></span>
81+
<span bm-pe-watch="row .num1"></span>
82+
<span bm-pe-watch="row. num1"></span>
83+
<span bm-pe-watch="row . num1"></span>
84+
<span bm-pe-watch="row . num2"></span>
85+
</li>
86+
87+
<li ng-switch-when="fieldIndex" ng-repeat="(rowIdx, row) in data">
88+
<span bm-pe-watch="data[rowIdx]"></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+
<span bm-pe-watch="row['str0']"></span>
99+
<span bm-pe-watch="row['str1']"></span>
100+
</li>
101+
102+
<li ng-switch-when="operators" ng-repeat="(rowIdx, row) in data">
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 | noop"></span>
120+
<span bm-pe-watch="rowIdx | noop | noop | noop"></span>
121+
<span bm-pe-watch="-rowIdx | noop"></span>
122+
<span bm-pe-watch="rowIdx | noop:1"></span>
123+
<span bm-pe-watch="rowIdx | noop:1 | noop"></span>
124+
<span bm-pe-watch="rowIdx | noop:1 | noop:2 | noop:3"></span>
125+
<span bm-pe-watch="rowIdx | noop:1:2:3:4:5"></span>
126+
<span bm-pe-watch="rowIdx | noop:rowIdx"></span>
127+
<span bm-pe-watch="rowIdx | noop:rowIdx:rowIdx:rowIdx"></span>
128+
<span bm-pe-watch="rowIdx | noop | noop:1 | noop"></span>
129+
<span bm-pe-watch="rowIdx | noop | noop:null:undefined:0"></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="func(1, 2, 3, 4)"></span>
138+
<span bm-pe-watch="row.func()"></span>
139+
<span bm-pe-watch="row.func(1)"></span>
140+
<span bm-pe-watch="row.func(1, 2)"></span>
141+
<span bm-pe-watch="row.func(1, 2, 3)"></span>
142+
<span bm-pe-watch="row.func(1, 2, 3, 4)"></span>
143+
<span bm-pe-watch="func(func())"></span>
144+
<span bm-pe-watch="func(func(), func())"></span>
145+
<span bm-pe-watch="row.func(row.func())"></span>
146+
<span bm-pe-watch="row.func(row.func(), row.func())"></span>
147+
</li>
148+
149+
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in data">
150+
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
151+
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
152+
<span bm-pe-watch-literal="{0: row, 1: rowIdx, 2: 3}"></span>
153+
<span bm-pe-watch-literal="{str: 'foo', num: rowIdx, b: true}"></span>
154+
<span bm-pe-watch-literal="{a: {b: {c: {d: e: {f: rowIdx}}}}}"></span>
155+
<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>
156+
</li>
157+
158+
<li ng-switch-when="arrayLiterals" ng-repeat="(rowIdx, row) in data">
159+
<span bm-pe-watch-literal="[rowIdx]"></span>
160+
<span bm-pe-watch-literal="[rowIdx, 0]"></span>
161+
<span bm-pe-watch-literal="[rowIdx, 0, 1]"></span>
162+
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2]"></span>
163+
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2, 3]"></span>
164+
<span bm-pe-watch-literal="[[], [rowIdx], [], [], [3], [[[]]]"></span>
165+
<span bm-pe-watch-literal="[rowIdx, undefined, null, true, false]"></span>
166+
<span bm-pe-watch-literal="[[][0], [0][0], [][rowIdx]]"></span>
167+
<span bm-pe-watch-literal="[0, rowIdx]"></span>
168+
<span bm-pe-watch-literal="[0, 1, rowIdx]"></span>
169+
<span bm-pe-watch-literal="[0, 1, 2, rowIdx]"></span>
170+
<span bm-pe-watch-literal="[0, 1, 2, 3, rowIdx]"></span>
171+
</li>
172+
173+
<!--
174+
<li ng-switch-when="" ng-repeat="(rowIdx, row) in data">
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+
<span bm-pe-watch=""></span>
186+
<span bm-pe-watch=""></span>
187+
</li>
188+
-->
189+
</ul>
190+
</div>
191+
</div>
192+
</div>

0 commit comments

Comments
 (0)