Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 81f539b

Browse files
vsavkinjbdeboer
authored andcommitted
perf(view_factory): add a benchmark that measures view_factory in isolation
Closes #1384
1 parent a101321 commit 81f539b

File tree

3 files changed

+226
-2
lines changed

3 files changed

+226
-2
lines changed

benchmark/web/bp.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,10 @@ bp.Document.addLinks = function() {
271271

272272
[
273273
// Add new benchmark suites here
274-
['tree.html', 'TreeComponent']
274+
['/tree.html', 'TreeComponent'],
275+
['/view_factory/view_factory.html', 'ViewFactory']
275276
].forEach((function (link) {
276-
linkHtml += '<a href="'+ link[0] +'">'+ link[1] +'</a>';
277+
linkHtml += '<a href="'+ link[0] +'">'+ link[1] +'</a> ';
277278
}));
278279

279280
if (linkDiv) {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
library angular.benchmark.compiler;
2+
3+
import 'package:angular/angular.dart';
4+
import 'package:angular/application_factory.dart';
5+
import 'package:angular/mock/module.dart';
6+
import 'package:benchmark_harness/benchmark_harness.dart';
7+
8+
import 'dart:html';
9+
import 'dart:js' as js;
10+
11+
12+
class ViewFactoryInvocaton {
13+
ViewFactory viewFactory;
14+
Scope scope;
15+
DirectiveInjector di;
16+
List<Node> elements;
17+
18+
ViewFactoryInvocaton(String template) {
19+
final injector = applicationFactory().run();
20+
final directiveMap = injector.get(DirectiveMap);
21+
final compiler = injector.get(Compiler);
22+
23+
elements = _getElements(template);
24+
scope = injector.get(Scope);
25+
di = injector.get(DirectiveInjector);
26+
viewFactory = compiler(elements, directiveMap);
27+
}
28+
29+
run() {
30+
viewFactory(scope, di, elements);
31+
}
32+
33+
List<Node > _getElements(String template) {
34+
var div = new DivElement()..setInnerHtml(template, treeSanitizer: new NullTreeSanitizer());
35+
return new List.from(div.nodes);
36+
}
37+
}
38+
39+
final TEMPLATE_TEXT_NO_NG_BINDING = '<span>{{1 + 2}}'
40+
'<span ng-if="1 != 2">left</span>'
41+
'<span ng-if="1 != 2">right</span>'
42+
'</span>';
43+
44+
final TEMPLATE_TEXT_WITH_NG_BINDING = '<span><span ng-class="{}">{{1 + 2}}</span>'
45+
'<span ng-if="1 != 2">left</span>'
46+
'<span ng-if="1 != 2">right</span>'
47+
'</span>';
48+
49+
final TEMPLATE_NO_TEXT_WITH_NG_BINDING = '<span><span ng-class="{}"></span>'
50+
'<span ng-if="1 != 2">left</span>'
51+
'<span ng-if="1 != 2">right</span>'
52+
'</span>';
53+
54+
final TEMPLATE_TEXT_WITH_NG_BINDING_3_TIMES = '<span>'
55+
'<span ng-class="{}">{{1 + 2}}</span>'
56+
'<span ng-class="{}">{{1 + 2}}</span>'
57+
'<span ng-class="{}">{{1 + 2}}</span>'
58+
'<span ng-if="1 != 2">left</span>'
59+
'<span ng-if="1 != 2">right</span>'
60+
'</span>';
61+
62+
63+
void main() {
64+
final templates = {
65+
"(text + ng-binding) * 3" : TEMPLATE_TEXT_WITH_NG_BINDING_3_TIMES,
66+
"text" : TEMPLATE_TEXT_NO_NG_BINDING,
67+
"text + ng-binding" : TEMPLATE_TEXT_WITH_NG_BINDING,
68+
"ng-binding" : TEMPLATE_NO_TEXT_WITH_NG_BINDING
69+
};
70+
71+
final t = document.querySelector("#templates");
72+
templates.keys.forEach((name) {
73+
t.appendHtml("<option value='$name'>$name</option>");
74+
});
75+
76+
viewFactory(_) {
77+
final b = new ViewFactoryInvocaton(templates[t.value]);
78+
int i = 5000;
79+
while (i -- > 0) b.run();
80+
}
81+
82+
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
83+
"name": "ViewFactory.call", "fn": new js.JsFunction.withThis(viewFactory)
84+
}));
85+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head lang="en">
4+
<meta charset="UTF-8">
5+
<title>Compilation</title>
6+
7+
<script src="../underscore.js"></script>
8+
<script src="../bp.js"></script>
9+
<link rel="stylesheet" href="../bootstrap.min.css">
10+
11+
<style>
12+
.bpLink { background: lightblue; padding: 1em; margin-bottom: 1.5em; }
13+
.row.average { font-weight: bold; background: #eee; border-bottom: 1px solid #CCC; padding: 12px 0; margin-bottom: 12px; }
14+
.row.headings { font-size: 18px; font-weight: bold; }
15+
.average .title { font-size: 28px; }
16+
.scrollable { max-height:250px !important; overflow-y: auto; }
17+
</style>
18+
19+
<script src="view_factory.dart" type="application/dart"></script>
20+
<script src="packages/browser/dart.js"></script>
21+
<script src="packages/browser/interop.js"></script>
22+
</head>
23+
<body>
24+
<div class="container-fluid">
25+
<div class="row">
26+
<div class="col-lg-12">
27+
<div id="benchmarkContainer">
28+
<div class="bpLink">
29+
Benchmark Versions:
30+
<span class="versionContent"></span>
31+
</div>
32+
<hr>
33+
<form role="form" class="form-vertical">
34+
<div class="form-group">
35+
<label for="sampleRange">
36+
Select number of samples to collect and average:
37+
<span id="sampleRangeValue"></span>
38+
</label>
39+
<input id="sampleRange" type="text" value="20">
40+
</div>
41+
</form>
42+
43+
<div class="btn-group">
44+
<select id="templates"></select>
45+
</div>
46+
47+
<div class="btn-group">
48+
<button class="loopBtn btn btn-default">Loop</button>
49+
<button class="onceBtn btn btn-default">Once</button>
50+
<button class="twentyFiveBtn btn btn-default">Loop 25x</button>
51+
</div>
52+
<hr>
53+
54+
<div class="table table-striped results-table">
55+
<div class="thead">
56+
<div class="row headings">
57+
<div class="th col-md-2 col-md-offset-2">
58+
test time (ms)
59+
</div>
60+
<div class="th col-md-2">
61+
gc time (ms)
62+
</div>
63+
<div class="th col-md-2">
64+
garbage (KB)
65+
</div>
66+
<div class="th col-md-2">
67+
retained memory (KB)
68+
</div>
69+
</div>
70+
</div>
71+
<div class="tbody info"></div>
72+
</div>
73+
74+
<script type="template" id="infoTemplate">
75+
<div class="row average">
76+
<div class="td col-md-2 title"><%= name %></div>
77+
<div class="td col-md-2">
78+
mean: <%= testTime.avg.mean.toFixed(2) %>ms
79+
&plusmn; <%= Math.round(testTime.avg.coefficientOfVariation * 100) %>%
80+
<br>
81+
(stddev <%= testTime.avg.stdDev.toFixed(2) %>)
82+
<br>
83+
(min <%= testTime.min.toFixed(2) %> /
84+
max <%= testTime.max.toFixed(2) %>)
85+
</div>
86+
<div class="td col-md-2">
87+
mean: <%= gcTime.avg.mean.toFixed(2) %>ms
88+
<br>
89+
(combined: <%= (testTime.avg.mean + gcTime.avg.mean).toFixed(2) %>ms)
90+
</div>
91+
<div class="td col-md-2">
92+
mean: <%= (garbageCount.avg.mean / 1e3).toFixed(2) %>KB
93+
</div>
94+
<div class="td col-md-2">
95+
mean: <%= (retainedCount.avg.mean / 1e3).toFixed(2) %>KB
96+
</div>
97+
</div>
98+
<div class="row scrollable">
99+
<div class="td col-md-2 col-md-offset-2">
100+
<div class="sampleContainer">
101+
<% _.each(testTime.history, function(time) { %>
102+
<%= time.toFixed(2) %>
103+
<br>
104+
<% }); %>
105+
</div>
106+
</div>
107+
<div class="td col-md-2">
108+
<div class="sampleContainer">
109+
<% _.each(gcTime.history, function(time) { %>
110+
<%= time.toFixed(2) %>
111+
<br>
112+
<% }); %>
113+
</div>
114+
</div>
115+
<div class="td col-md-2">
116+
<div class="sampleContainer">
117+
<% _.each(garbageCount.history, function(count) { %>
118+
<%= (count / 1e3).toFixed(2) %>
119+
<br>
120+
<% }); %>
121+
</div>
122+
</div>
123+
<div class="td col-md-2">
124+
<div class="sampleContainer">
125+
<% _.each(retainedCount.history, function(count) { %>
126+
<%= (count / 1e3).toFixed(2) %>
127+
<br>
128+
<% }); %>
129+
</div>
130+
</div>
131+
</div>
132+
</script>
133+
</div>
134+
</div>
135+
</div>
136+
</div>
137+
</body>
138+
</html>

0 commit comments

Comments
 (0)