Skip to content

Commit 6187b80

Browse files
committed
benchmark(compiler): add a benchmark measuring view instantiation in AngularDart 1.0
1 parent c6f14dd commit 6187b80

File tree

17 files changed

+539
-40
lines changed

17 files changed

+539
-40
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ packages/
55
.buildlog
66
node_modules
77
packages
8-
8+
.pub
99
.DS_STORE
1010

1111
# Or the files created by dart2js.

gulpfile.js

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -248,59 +248,83 @@ gulp.task('analyze/dartanalyzer', function(done) {
248248
// ------------------
249249
// BENCHMARKS JS
250250

251-
gulp.task('benchmarks/build.benchpress.js', function () {
251+
gulp.task('benchmarks/internal.benchpress.js', function () {
252252
benchpress.build({
253253
benchmarksPath: 'build/js/benchmarks/lib',
254254
buildPath: 'build/benchpress/js'
255255
})
256256
});
257257

258-
gulp.task('benchmarks/build.js', function() {
258+
gulp.task('benchmarks/external.benchpress.js', function () {
259+
benchpress.build({
260+
benchmarksPath: 'build/js/benchmarks_external/lib',
261+
buildPath: 'build/benchpress/js'
262+
})
263+
});
264+
265+
gulp.task('benchmarks/internal.js', function() {
259266
runSequence(
260267
['jsRuntime/build', 'modules/build.prod.js'],
261-
'benchmarks/build.benchpress.js'
268+
'benchmarks/internal.benchpress.js'
269+
);
270+
});
271+
272+
gulp.task('benchmarks/external.js', function() {
273+
runSequence(
274+
['jsRuntime/build', 'modules/build.prod.js'],
275+
'benchmarks/external.benchpress.js'
262276
);
263277
});
264278

265279

266280
// ------------------
267281
// BENCHMARKS DART
268282

269-
gulp.task('benchmarks/build.dart2js.dart', function () {
270-
return gulp.src([
271-
"build/dart/benchmarks/lib/**/benchmark.dart"
272-
]).pipe($.shell(['dart2js --package-root="build/dart/benchmarks/packages" -o "<%= file.path %>.js" <%= file.path %>']));
273-
});
283+
function benchmarkDart2Js(buildPath, done) {
274284

275-
gulp.task('benchmarks/create-bpconf.dart', function () {
276-
var bpConfContent = "module.exports = function(c) {c.set({scripts: [{src: 'benchmark.dart.js'}]});}";
277-
var createBpConfJs = es.map(function(file, cb) {
278-
var dir = path.dirname(file.path);
279-
fs.writeFileSync(path.join(dir, "bp.conf.js"), bpConfContent);
280-
cb();
281-
});
285+
mergeStreams(dart2jsStream(), bpConfStream())
286+
.on('end', function() {
287+
runBenchpress();
288+
done();
289+
});
282290

283-
return gulp.src([
284-
"build/dart/benchmarks/lib/**/benchmark.dart"
285-
]).pipe(createBpConfJs);
286-
});
291+
function dart2jsStream() {
292+
return gulp.src([
293+
buildPath+"/lib/**/benchmark.dart"
294+
]).pipe($.shell(['dart2js --package-root="'+buildPath+'/packages" -o "<%= file.path %>.js" <%= file.path %>']));
295+
}
287296

288-
gulp.task('benchmarks/build.benchpress.dart', function () {
289-
benchpress.build({
290-
benchmarksPath: 'build/dart/benchmarks/lib',
291-
buildPath: 'build/benchpress/dart'
292-
})
297+
function bpConfStream() {
298+
var bpConfContent = "module.exports = function(c) {c.set({scripts: [{src: 'benchmark.dart.js'}]});}";
299+
var createBpConfJs = es.map(function(file, cb) {
300+
var dir = path.dirname(file.path);
301+
fs.writeFileSync(path.join(dir, "bp.conf.js"), bpConfContent);
302+
cb();
303+
});
304+
305+
return gulp.src([
306+
buildPath+"/lib/**/benchmark.dart"
307+
]).pipe(createBpConfJs);
308+
}
309+
310+
function runBenchpress() {
311+
benchpress.build({
312+
benchmarksPath: buildPath+'/lib',
313+
buildPath: 'build/benchpress/dart'
314+
});
315+
}
316+
}
317+
318+
gulp.task('benchmarks/internal.dart', ['modules/build.dart'], function(done) {
319+
benchmarkDart2Js('build/dart/benchmarks', done);
293320
});
294321

295-
gulp.task('benchmarks/build.dart', function() {
296-
runSequence(
297-
'modules/build.dart',
298-
'benchmarks/build.dart2js.dart',
299-
'benchmarks/create-bpconf.dart',
300-
'benchmarks/build.benchpress.dart'
301-
);
322+
gulp.task('benchmarks/external.dart', ['modules/build.dart'], function(done) {
323+
benchmarkDart2Js('build/dart/benchmarks_external', done);
302324
});
303325

326+
gulp.task('benchmarks/build.dart', ['benchmarks/internal.dart', 'benchmarks/external.dart']);
327+
304328

305329

306330
// ------------------

modules/benchmarks/pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ dependencies:
66
path: ../facade
77
di:
88
path: ../di
9+
reflection:
10+
path: ../reflection
911
core:
1012
path: ../core
1113
change_detection:

modules/benchmarks/src/compiler/benchmark.es5

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
Promise.all([
22
System.import('benchmarks/compiler/selector_benchmark'),
3-
System.import('benchmarks/compiler/compiler_benchmark'),
4-
System.import('benchmarks/compiler/compiler_benchmark_ng13')
3+
System.import('benchmarks/compiler/compiler_benchmark')
54
]).then(function (benchmarks) {
65
benchmarks.forEach(function(bm) {
76
bm.main();

modules/benchmarks/src/compiler/bp.conf.es5

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ module.exports = function(config) {
55
{src: '/js/es6-module-loader-sans-promises.src.js'},
66
{src: '/js/extension-register.js'},
77
{src: 'register_system.js'},
8-
{src: 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js'},
98
{src: 'benchmark.js'}
109
]
1110
});

modules/benchmarks/src/compiler/compiler_benchmark.js

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {AnnotatedType} from 'core/compiler/annotated_type';
77

88
import {Parser} from 'change_detection/parser/parser';
99
import {Lexer} from 'change_detection/parser/lexer';
10+
import {ProtoRecordRange} from 'change_detection/record_range';
1011

1112
import {Compiler} from 'core/compiler/compiler';
1213
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
@@ -15,12 +16,70 @@ import {Component} from 'core/annotations/annotations';
1516
import {Decorator} from 'core/annotations/annotations';
1617
import {TemplateConfig} from 'core/annotations/template_config';
1718

19+
import {reflector} from 'reflection/reflection';
20+
1821
var COUNT = 30;
1922

2023
var compiler;
2124
var annotatedComponent;
2225

2326
function setup() {
27+
reflector.registerType(BenchmarkComponent, {
28+
"factory": () => new BenchmarkComponent(),
29+
"parameters": [],
30+
"annotations" : [new Component({template: new TemplateConfig({directives: [Dir0, Dir1, Dir2, Dir3, Dir4]})})]
31+
});
32+
33+
reflector.registerType(Dir0, {
34+
"factory": () => new Dir0(),
35+
"parameters": [],
36+
"annotations" : [new Decorator({selector: '[dir0]', bind: {'attr0': 'prop'}})]
37+
});
38+
39+
reflector.registerType(Dir1, {
40+
"factory": (dir0) => new Dir1(dir0),
41+
"parameters": [[Dir0]],
42+
"annotations" : [new Decorator({selector: '[dir1]', bind: {'attr1': 'prop'}})]
43+
});
44+
45+
reflector.registerType(Dir2, {
46+
"factory": (dir1) => new Dir2(dir1),
47+
"parameters": [[Dir1]],
48+
"annotations" : [new Decorator({selector: '[dir2]', bind: {'attr2': 'prop'}})]
49+
});
50+
51+
reflector.registerType(Dir3, {
52+
"factory": (dir2) => new Dir3(dir2),
53+
"parameters": [[Dir2]],
54+
"annotations" : [new Decorator({selector: '[dir3]', bind: {'attr3': 'prop'}})]
55+
});
56+
57+
reflector.registerType(Dir4, {
58+
"factory": (dir3) => new Dir4(dir3),
59+
"parameters": [[Dir3]],
60+
"annotations" : [new Decorator({selector: '[dir4]', bind: {'attr4': 'prop'}})]
61+
});
62+
63+
reflector.registerGetters({
64+
"inter0": (a) => a.inter0, "inter1": (a) => a.inter1,
65+
"inter2": (a) => a.inter2, "inter3": (a) => a.inter3, "inter4": (a) => a.inter4,
66+
67+
"value0": (a) => a.value0, "value1": (a) => a.value1,
68+
"value2": (a) => a.value2, "value3": (a) => a.value3, "value4": (a) => a.value4,
69+
70+
"prop" : (a) => a.prop
71+
});
72+
73+
reflector.registerSetters({
74+
"inter0": (a,v) => a.inter0 = v, "inter1": (a,v) => a.inter1 = v,
75+
"inter2": (a,v) => a.inter2 = v, "inter3": (a,v) => a.inter3 = v, "inter4": (a,v) => a.inter4 = v,
76+
77+
"value0": (a,v) => a.value0 = v, "value1": (a,v) => a.value1 = v,
78+
"value2": (a,v) => a.value2 = v, "value3": (a,v) => a.value3 = v, "value4": (a,v) => a.value4 = v,
79+
80+
"prop": (a,v) => a.prop = v
81+
});
82+
2483
var reader = new CachingDirectiveMetadataReader();
2584
compiler = new Compiler(null, reader, new Parser(new Lexer()));
2685
annotatedComponent = reader.annotatedType(BenchmarkComponent);
@@ -48,6 +107,19 @@ export function main() {
48107
compiler.compileWithCache(null, annotatedComponent, cloned);
49108
});
50109
});
110+
111+
benchmark(`instantiate 5*${COUNT} element with bindings`, function() {
112+
var template = loadTemplate('templateWithBindings', COUNT);
113+
var protoView = compiler.compileWithCache(null, annotatedComponent, template);
114+
var rootRecordRange = new ProtoRecordRange().instantiate(null, new Object());
115+
116+
benchmarkStep('run', function() {
117+
var view = protoView.instantiate(null, null, null);
118+
// also include adding / removing the RecordRange from the parent in the benchmark.
119+
rootRecordRange.addRange(view.recordRange);
120+
view.recordRange.remove();
121+
});
122+
});
51123
}
52124

53125
function loadTemplate(templateId, repeatCount) {
@@ -90,31 +162,39 @@ class Dir0 {}
90162
'attr1': 'prop'
91163
}
92164
})
93-
class Dir1 {}
165+
class Dir1 {
166+
constructor(dir0:Dir0) {}
167+
}
94168

95169
@Decorator({
96170
selector: '[dir2]',
97171
bind: {
98172
'attr2': 'prop'
99173
}
100174
})
101-
class Dir2 {}
175+
class Dir2 {
176+
constructor(dir1:Dir1) {}
177+
}
102178

103179
@Decorator({
104180
selector: '[dir3]',
105181
bind: {
106182
'attr3': 'prop'
107183
}
108184
})
109-
class Dir3 {}
185+
class Dir3 {
186+
constructor(dir2:Dir2) {}
187+
}
110188

111189
@Decorator({
112190
selector: '[dir4]',
113191
bind: {
114192
'attr4': 'prop'
115193
}
116194
})
117-
class Dir4 {}
195+
class Dir4 {
196+
constructor(dir3:Dir3) {}
197+
}
118198

119199
@Component({
120200
template: new TemplateConfig({
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name: benchmarks_external
2+
environment:
3+
sdk: '>=1.4.0'
4+
dependencies:
5+
angular: ">=1.0.0 <2.0.0"
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
library benchmarks.benchpress;
2+
3+
import 'dart:js' as js;
4+
import 'dart:html';
5+
import 'dart:async';
6+
7+
// TODO: move the functionality of this module into benchpress and replace this
8+
// file with a Dart wrapper!
9+
10+
var _benchmarkNames = [];
11+
12+
_benchmarkId(index) {
13+
return "benchmark${index}";
14+
}
15+
16+
_useBenchmark(index) {
17+
var search = window.location.search;
18+
if (search.length > 0) {
19+
search = search.substring(1);
20+
}
21+
if (search.length > 0) {
22+
return search == _benchmarkId(index);
23+
} else {
24+
return true;
25+
}
26+
}
27+
28+
_onLoad(callback) {
29+
var isReady = document.readyState == 'complete';
30+
if (isReady) {
31+
Timer.run(callback);
32+
} else {
33+
window.addEventListener('load', (event) => callback(), false);
34+
}
35+
}
36+
37+
_createBenchmarkMenu() {
38+
var div = document.createElement('div');
39+
div.innerHtml += '<h1>Benchmarks:</h1><a class="btn btn-default" href="?">All</a>';
40+
for (var i=0; i<_benchmarkNames.length; i++) {
41+
var activeClass = _useBenchmark(i) ? 'active' : '';
42+
div.innerHtml += '<a class="btn btn-default ${activeClass}" href="?${_benchmarkId(i)}">${_benchmarkNames[i]}</a>';
43+
}
44+
document.body.insertBefore(div, document.body.childNodes[0]);
45+
}
46+
47+
benchmark(name, stepsCreationCallback) {
48+
_benchmarkNames.add(name);
49+
if (_benchmarkNames.length == 2) {
50+
_onLoad(_createBenchmarkMenu);
51+
}
52+
if (_useBenchmark(_benchmarkNames.length-1)) {
53+
stepsCreationCallback();
54+
}
55+
}
56+
57+
benchmarkStep(name, callback) {
58+
var benchmarkName = _benchmarkNames[_benchmarkNames.length-1];
59+
js.context['benchmarkSteps'].add(new js.JsObject.jsify({
60+
"name": benchmarkName + '#' + name,
61+
"fn": new js.JsFunction.withThis((_) => callback())
62+
}));
63+
}

0 commit comments

Comments
 (0)