diff --git a/.travis.yml b/.travis.yml
index b7e170454f..bb739297b4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,5 @@
language: node_js
+sudo: false
node_js:
- '0.10'
env:
diff --git a/gulpfile.js b/gulpfile.js
index fa29b2a741..9d7225a095 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -8,11 +8,12 @@ var clean = require('./tools/build/clean');
var deps = require('./tools/build/deps');
var transpile = require('./tools/build/transpile');
var html = require('./tools/build/html');
-var benchpress = require('./tools/build/benchpress');
var pubspec = require('./tools/build/pubspec');
+var pubbuild = require('./tools/build/pubbuild');
var dartanalyzer = require('./tools/build/dartanalyzer');
var jsserve = require('./tools/build/jsserve');
var pubserve = require('./tools/build/pubserve');
+
var DART_SDK = require('./tools/build/dartdetect')(gulp);
// -----------------------
// configuration
@@ -43,23 +44,18 @@ var _HTLM_DEFAULT_SCRIPTS_JS = [
var CONFIG = {
- commands: {
- pub: process.platform === 'win32' ? 'pub.bat' : 'pub',
- dartanalyzer: process.platform === "win32" ? "dartanalyzer.bat" : "dartanalyzer"
- },
dest: {
js: {
all: 'dist/js',
dev: 'dist/js/dev',
- prod: 'dist/js/prod'
+ prod: 'dist/js/prod',
+ dart2js: 'dist/js/dart2js'
},
dart: 'dist/dart'
},
srcFolderMapping: {
'default': 'lib',
- // need a tmp folder as benchpress does not support
- // inplace generation of the benchmarks...
- '**/benchmark*/**': 'perf_tmp',
+ '**/benchmark*/**': 'web',
'**/example*/**': 'web'
},
deps: {
@@ -76,12 +72,12 @@ var CONFIG = {
},
transpile: {
src: {
- js: ['modules/**/*.js', 'modules/**/*.es6'],
- dart: ['modules/**/*.js']
+ js: ['modules/**/*.js', 'modules/**/*.es6', '!modules/**/perf/**/*'],
+ dart: ['modules/**/*.js', '!modules/**/perf/**/*']
},
copy: {
- js: ['modules/**/*.es5'],
- dart: ['modules/**/*.dart']
+ js: ['modules/**/*.es5', '!modules/**/perf/**/*'],
+ dart: ['modules/**/*.dart', '!modules/**/perf/**/*']
},
options: {
js: {
@@ -122,14 +118,6 @@ var CONFIG = {
}
}
},
- benchpress: {
- configFile: {
- content: 'module.exports=function(){};\n',
- name: 'bp.conf.js'
- },
- mainHtmls: '*/perf_tmp/**/main.html',
- outputFolderName: 'web'
- },
pubspec: {
src: 'modules/*/pubspec.yaml'
}
@@ -213,31 +201,6 @@ gulp.task('build/html.dart', html(gulp, gulpPlugins, {
scriptsPerFolder: CONFIG.html.scriptsPerFolder.dart
}));
-// ------------
-// benchpress
-
-gulp.task('build/benchpress.js.dev', benchpress(gulp, gulpPlugins, {
- mainHtmls: CONFIG.benchpress.mainHtmls,
- configFile: CONFIG.benchpress.configFile,
- buildDir: CONFIG.dest.js.dev,
- outputFolderName: CONFIG.benchpress.outputFolderName
-}));
-
-gulp.task('build/benchpress.js.prod', benchpress(gulp, gulpPlugins, {
- mainHtmls: CONFIG.benchpress.mainHtmls,
- configFile: CONFIG.benchpress.configFile,
- buildDir: CONFIG.dest.js.prod,
- outputFolderName: CONFIG.benchpress.outputFolderName
-}));
-
-gulp.task('build/benchpress.dart', benchpress(gulp, gulpPlugins, {
- mainHtmls: CONFIG.benchpress.mainHtmls,
- configFile: CONFIG.benchpress.configFile,
- buildDir: CONFIG.dest.dart,
- outputFolderName: CONFIG.benchpress.outputFolderName
-}));
-
-
// ------------
// pubspec
@@ -248,7 +211,7 @@ gulp.task('build/pubspec.dart', pubspec(gulp, gulpPlugins, {
}));
// ------------
-// pubspec
+// dartanalyzer
gulp.task('build/analyze.dart', dartanalyzer(gulp, gulpPlugins, {
dest: CONFIG.dest.dart,
@@ -256,14 +219,30 @@ gulp.task('build/analyze.dart', dartanalyzer(gulp, gulpPlugins, {
srcFolderMapping: CONFIG.srcFolderMapping
}));
+// ------------
+// pubbuild
+
+gulp.task('build/pubbuild.dart', pubbuild(gulp, gulpPlugins, {
+ src: CONFIG.dest.dart,
+ dest: CONFIG.dest.js.dart2js,
+ command: DART_SDK.PUB
+}));
+
// ------------------
// web servers
gulp.task('serve.js.dev', jsserve(gulp, gulpPlugins, {
- path: CONFIG.dest.js.dev
+ path: CONFIG.dest.js.dev,
+ port: 8000
}));
gulp.task('serve.js.prod', jsserve(gulp, gulpPlugins, {
- path: CONFIG.dest.js.prod
+ path: CONFIG.dest.js.prod,
+ port: 8001
+}));
+
+gulp.task('serve.js.dart2js', jsserve(gulp, gulpPlugins, {
+ path: CONFIG.dest.js.dart2js,
+ port: 8002
}));
gulp.task('serve/examples.dart', pubserve(gulp, gulpPlugins, {
@@ -343,22 +322,20 @@ gulp.task('build.dart', function() {
return runSequence(
['build/transpile.dart', 'build/html.dart'],
'build/pubspec.dart',
- 'build/benchpress.dart',
+ 'build/pubbuild.dart',
'build/analyze.dart'
);
});
gulp.task('build.js.dev', function() {
return runSequence(
- ['build/deps.js.dev', 'build/transpile.js.dev', 'build/html.js.dev'],
- 'build/benchpress.js.dev'
+ ['build/deps.js.dev', 'build/transpile.js.dev', 'build/html.js.dev']
);
});
gulp.task('build.js.prod', function() {
return runSequence(
- ['build/deps.js.prod', 'build/transpile.js.prod', 'build/html.js.prod'],
- 'build/benchpress.js.prod'
+ ['build/deps.js.prod', 'build/transpile.js.prod', 'build/html.js.prod']
);
});
diff --git a/modules/benchmarks/pubspec.yaml b/modules/benchmarks/pubspec.yaml
index 67371437d7..ef8e17b45f 100644
--- a/modules/benchmarks/pubspec.yaml
+++ b/modules/benchmarks/pubspec.yaml
@@ -12,6 +12,4 @@ dependencies:
path: ../core
change_detection:
path: ../change_detection
- benchpress:
- path: ../benchpress
browser: '>=0.10.0 <0.11.0'
diff --git a/modules/benchmarks/src/change_detection/change_detection_benchmark.html b/modules/benchmarks/src/change_detection/change_detection_benchmark.html
new file mode 100644
index 0000000000..8f1707ae77
--- /dev/null
+++ b/modules/benchmarks/src/change_detection/change_detection_benchmark.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+$SCRIPTS$
+
+
\ No newline at end of file
diff --git a/modules/benchmarks/src/change_detection/change_detection_benchmark.js b/modules/benchmarks/src/change_detection/change_detection_benchmark.js
index c49d1f1550..698b92ac71 100644
--- a/modules/benchmarks/src/change_detection/change_detection_benchmark.js
+++ b/modules/benchmarks/src/change_detection/change_detection_benchmark.js
@@ -3,7 +3,7 @@ import {Parser} from 'change_detection/parser/parser';
import {Lexer} from 'change_detection/parser/lexer';
import {reflector} from 'reflection/reflection';
import {isPresent} from 'facade/lang';
-import {benchmark, benchmarkStep} from 'benchpress/benchpress';
+import {document, DOM} from 'facade/dom';
import {
ChangeDetector,
@@ -12,7 +12,7 @@ import {
} from 'change_detection/change_detector';
-var ITERATIONS = 200000;
+var ITERATIONS = 500000;
class Obj {
field0;
@@ -155,28 +155,25 @@ function setUpChangeDetection() {
export function main () {
setUpReflector();
+ var baselineHead = setUpBaseline();
+ var ng2ChangeDetector = setUpChangeDetection();
- benchmark(`Baseline`, function () {
- var head = setUpBaseline();
-
- benchmarkStep('run', function () {
- var current = head;
- while (isPresent(current)) {
- if (current.getter(current.obj) !== current.previousValue) {
- throw "should not happen";
- }
- current = current.next;
+ function baselineDetectChanges(_) {
+ var current = baselineHead;
+ while (isPresent(current)) {
+ if (current.getter(current.obj) !== current.previousValue) {
+ throw "should not happen";
}
- });
- });
+ current = current.next;
+ }
+ }
- benchmark(`Change Detection`, function() {
- var cd = setUpChangeDetection();
+ function ng2DetectChanges(_) {
+ ng2ChangeDetector.detectChanges();
+ }
- benchmarkStep('run', function() {
- cd.detectChanges();
- });
- });
+ DOM.on(DOM.querySelector(document, '#ng2DetectChanges'), 'click', ng2DetectChanges);
+ DOM.on(DOM.querySelector(document, '#baselineDetectChanges'), 'click', baselineDetectChanges);
}
diff --git a/modules/benchmarks/src/change_detection/main.html b/modules/benchmarks/src/change_detection/main.html
deleted file mode 100644
index 3995f8ae30..0000000000
--- a/modules/benchmarks/src/change_detection/main.html
+++ /dev/null
@@ -1 +0,0 @@
-$SCRIPTS$
\ No newline at end of file
diff --git a/modules/benchmarks/src/change_detection/main.js b/modules/benchmarks/src/change_detection/main.js
deleted file mode 100644
index 5b55ee8923..0000000000
--- a/modules/benchmarks/src/change_detection/main.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import * as change_detection_benchmark from './change_detection_benchmark';
-
-export function main() {
- change_detection_benchmark.main();
-}
diff --git a/modules/benchmarks/src/compiler/main.html b/modules/benchmarks/src/compiler/compiler_benchmark.html
similarity index 92%
rename from modules/benchmarks/src/compiler/main.html
rename to modules/benchmarks/src/compiler/compiler_benchmark.html
index 178588bd7d..460bb9bf54 100644
--- a/modules/benchmarks/src/compiler/main.html
+++ b/modules/benchmarks/src/compiler/compiler_benchmark.html
@@ -1,4 +1,9 @@
-$SCRIPTS$
+
+
+
+
+
+
@@ -30,3 +35,8 @@ $SCRIPTS$
+
+$SCRIPTS$
+
+
+
\ No newline at end of file
diff --git a/modules/benchmarks/src/compiler/compiler_benchmark.js b/modules/benchmarks/src/compiler/compiler_benchmark.js
index 67325a015a..6eca478c1e 100644
--- a/modules/benchmarks/src/compiler/compiler_benchmark.js
+++ b/modules/benchmarks/src/compiler/compiler_benchmark.js
@@ -1,5 +1,3 @@
-import {benchmark, benchmarkStep} from 'benchpress/benchpress';
-
import {DOM, document} from 'facade/dom';
import {isBlank, Type} from 'facade/lang';
import {MapWrapper} from 'facade/collection';
@@ -20,10 +18,7 @@ import {reflector} from 'reflection/reflection';
var COUNT = 30;
-var compiler;
-var annotatedComponent;
-
-function setup() {
+function setupReflector() {
reflector.registerType(BenchmarkComponent, {
"factory": () => new BenchmarkComponent(),
"parameters": [],
@@ -79,47 +74,34 @@ function setup() {
"prop": (a,v) => a.prop = v
});
-
- var reader = new CachingDirectiveMetadataReader();
- compiler = new Compiler(null, reader, new Parser(new Lexer()), new CompilerCache());
- annotatedComponent = reader.annotatedType(BenchmarkComponent);
}
export function main() {
- setup();
+ setupReflector();
+ var reader = new DirectiveMetadataReader();
+ var cache = new CompilerCache();
+ var compiler = new Compiler(null, reader, new Parser(new Lexer()), cache);
+ var annotatedComponent = reader.annotatedType(BenchmarkComponent);
- benchmark(`Compiler.compile 5*${COUNT} element no bindings`, function() {
- var template = loadTemplate('templateNoBindings', COUNT);
+ var templateNoBindings = loadTemplate('templateNoBindings', COUNT);
+ var templateWithBindings = loadTemplate('templateWithBindings', COUNT);
- benchmarkStep('run', function() {
- // Need to clone every time as the compiler might modify the template!
- var cloned = DOM.clone(template);
- compiler.compileAllLoaded(null, annotatedComponent, cloned);
- });
- });
+ function compileNoBindings(_) {
+ // Need to clone every time as the compiler might modify the template!
+ var cloned = DOM.clone(templateNoBindings);
+ cache.clear();
+ compiler.compileAllLoaded(null, annotatedComponent, cloned);
+ }
- benchmark(`Compiler.compile 5*${COUNT} element with bindings`, function() {
- var template = loadTemplate('templateWithBindings', COUNT);
+ function compileWithBindings(_) {
+ // Need to clone every time as the compiler might modify the template!
+ var cloned = DOM.clone(templateWithBindings);
+ cache.clear();
+ compiler.compileAllLoaded(null, annotatedComponent, cloned);
+ }
- benchmarkStep('run', function() {
- // Need to clone every time as the compiler might modify the template!
- var cloned = DOM.clone(template);
- compiler.compileAllLoaded(null, annotatedComponent, cloned);
- });
- });
-
- benchmark(`instantiate 5*${COUNT} element with bindings`, function() {
- var template = loadTemplate('templateWithBindings', COUNT);
- var protoView = compiler.compileWithCache(null, annotatedComponent, template);
- var rootRecordRange = new ProtoRecordRange().instantiate(null, null);
-
- benchmarkStep('run', function() {
- var view = protoView.instantiate(null, null, null);
- // also include adding / removing the RecordRange from the parent in the benchmark.
- rootRecordRange.addRange(view.recordRange);
- view.recordRange.remove();
- });
- });
+ DOM.on(DOM.querySelector(document, '#compileNoBindings'), 'click', compileNoBindings);
+ DOM.on(DOM.querySelector(document, '#compileWithBindings'), 'click', compileWithBindings);
}
function loadTemplate(templateId, repeatCount) {
@@ -132,22 +114,6 @@ function loadTemplate(templateId, repeatCount) {
return DOM.createTemplate(result);
}
-// Caching reflector as reflection in Dart using Mirrors
-class CachingDirectiveMetadataReader extends DirectiveMetadataReader {
- _cache: Map;
- constructor() {
- this._cache = MapWrapper.create();
- }
- annotatedType(type:Type):AnnotatedType {
- var result = MapWrapper.get(this._cache, type);
- if (isBlank(result)) {
- result = super.annotatedType(type);
- MapWrapper.set(this._cache, type, result);
- }
- return result;
- }
-}
-
@Decorator({
selector: '[dir0]',
bind: {
diff --git a/modules/benchmarks/src/compiler/main.js b/modules/benchmarks/src/compiler/main.js
deleted file mode 100644
index 3a3a19252c..0000000000
--- a/modules/benchmarks/src/compiler/main.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import * as sbm from './selector_benchmark';
-import * as cbm from './compiler_benchmark';
-
-export function main() {
- sbm.main();
- cbm.main();
-}
diff --git a/modules/benchmarks/src/compiler/selector_benchmark.html b/modules/benchmarks/src/compiler/selector_benchmark.html
new file mode 100644
index 0000000000..3c2d8dd0e1
--- /dev/null
+++ b/modules/benchmarks/src/compiler/selector_benchmark.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+$SCRIPTS$
+
+
+
\ No newline at end of file
diff --git a/modules/benchmarks/src/compiler/selector_benchmark.js b/modules/benchmarks/src/compiler/selector_benchmark.js
index 509d710902..e0e6cab4de 100644
--- a/modules/benchmarks/src/compiler/selector_benchmark.js
+++ b/modules/benchmarks/src/compiler/selector_benchmark.js
@@ -1,63 +1,56 @@
-import {benchmark, benchmarkStep} from 'benchpress/benchpress';
+import {document, DOM} from 'facade/dom';
import {SelectorMatcher} from "core/compiler/selector";
import {CssSelector} from "core/compiler/selector";
import {StringWrapper, Math} from 'facade/lang';
import {ListWrapper} from 'facade/collection';
-var fixedMatcher;
-var fixedSelectorStrings = [];
-var fixedSelectors = [];
-
var COUNT = 1000;
export function main() {
- setup(COUNT);
-
- benchmark(`cssSelector.parse * ${COUNT}`, function() {
- benchmarkStep(`run`, function() {
- var result = [];
- for (var i=0; i {
- matchCount += selected;
- });
- }
- return matchCount;
- });
- });
-}
-
-function setup(count) {
- for (var i=0; i {
+ matchCount += selected;
+ });
+ }
+ return matchCount;
+ }
+
+ DOM.on(DOM.querySelector(document, '#parse'), 'click', parse);
+ DOM.on(DOM.querySelector(document, '#addSelectable'), 'click', addSelectable);
+ DOM.on(DOM.querySelector(document, '#match'), 'click', match);
}
function randomSelector() {
diff --git a/modules/benchmarks/src/di/di_benchmark.html b/modules/benchmarks/src/di/di_benchmark.html
new file mode 100644
index 0000000000..b779dca771
--- /dev/null
+++ b/modules/benchmarks/src/di/di_benchmark.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+$SCRIPTS$
+
+
diff --git a/modules/benchmarks/src/di/di_benchmark.js b/modules/benchmarks/src/di/di_benchmark.js
new file mode 100644
index 0000000000..fffcf3ee70
--- /dev/null
+++ b/modules/benchmarks/src/di/di_benchmark.js
@@ -0,0 +1,113 @@
+import {Injector, Key} from "di/di";
+import {reflector} from 'reflection/reflection';
+import {document, DOM} from 'facade/dom';
+
+var count = 0;
+
+function setupReflector() {
+ reflector.registerType(A, {
+ 'factory': () => new A(),
+ 'parameters': [],
+ 'annotations' : []
+ });
+ reflector.registerType(B, {
+ 'factory': (a) => new B(a),
+ 'parameters': [[A]],
+ 'annotations' : []
+ });
+ reflector.registerType(C, {
+ 'factory': (b) => new C(b),
+ 'parameters': [[B]],
+ 'annotations' : []
+ });
+ reflector.registerType(D, {
+ 'factory': (c,b) => new D(c,b),
+ 'parameters': [[C],[B]],
+ 'annotations' : []
+ });
+ reflector.registerType(E, {
+ 'factory': (d,c) => new E(d,c),
+ 'parameters': [[D],[C]],
+ 'annotations' : []
+ });
+}
+
+export function main() {
+ setupReflector();
+ var bindings = [A, B, C, D, E];
+ var injector = new Injector(bindings);
+
+ var D_KEY = Key.get(D);
+ var E_KEY = Key.get(E);
+ var childInjector = injector.
+ createChild([]).
+ createChild([]).
+ createChild([]).
+ createChild([]).
+ createChild([]);
+
+ function getByToken (_) {
+ for (var i = 0; i < 20000; ++i) {
+ injector.get(D);
+ injector.get(E);
+ }
+ }
+ function getByKey(_) {
+ for (var i = 0; i < 20000; ++i) {
+ injector.get(D_KEY);
+ injector.get(E_KEY);
+ }
+ }
+
+ function getChild (_) {
+ for (var i = 0; i < 20000; ++i) {
+ childInjector.get(D);
+ childInjector.get(E);
+ }
+ }
+
+ function instantiate (_) {
+ for (var i = 0; i < 5000; ++i) {
+ var child = injector.createChild([E]);
+ child.get(E);
+ }
+ }
+
+ DOM.on(DOM.querySelector(document, '#getByToken'), 'click', getByToken);
+ DOM.on(DOM.querySelector(document, '#getByKey'), 'click', getByKey);
+ DOM.on(DOM.querySelector(document, '#getChild'), 'click', getChild);
+ DOM.on(DOM.querySelector(document, '#instantiate'), 'click', instantiate);
+}
+
+
+
+
+class A {
+ constructor() {
+ count++;
+ }
+}
+
+class B {
+ constructor(a:A) {
+ count++;
+ }
+}
+
+class C {
+ constructor(b:B) {
+ count++;
+ }
+}
+
+class D {
+ constructor(c:C, b:B) {
+ count++;
+ }
+}
+
+class E {
+ constructor(d:D, c:C) {
+ count++;
+ }
+}
diff --git a/modules/benchmarks/src/di/injector_get_benchmark.js b/modules/benchmarks/src/di/injector_get_benchmark.js
deleted file mode 100644
index c3cc8c95fd..0000000000
--- a/modules/benchmarks/src/di/injector_get_benchmark.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import {Injector} from "di/di";
-
-var count = 0;
-
-export function run () {
- var bindings = [A, B, C, D, E];
- var injector = new Injector(bindings);
-
- for (var i = 0; i < 20000; ++i) {
- injector.get(D);
- injector.get(E);
- }
-}
-
-class A {
- constructor() {
- count++;
- }
-}
-
-class B {
- constructor(a:A) {
- count++;
- }
-}
-
-class C {
- constructor(b:B) {
- count++;
- }
-}
-
-class D {
- constructor(c:C, b:B) {
- count++;
- }
-}
-
-class E {
- constructor(d:D, c:C) {
- count++;
- }
-}
diff --git a/modules/benchmarks/src/di/injector_get_by_key_benchmark.js b/modules/benchmarks/src/di/injector_get_by_key_benchmark.js
deleted file mode 100644
index 6fd8669651..0000000000
--- a/modules/benchmarks/src/di/injector_get_by_key_benchmark.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import {Injector, Key} from "di/di";
-
-var count = 0;
-
-export function run () {
- var bindings = [A, B, C, D, E];
- var injector = new Injector(bindings);
-
- var D_KEY = Key.get(D);
- var E_KEY = Key.get(E);
-
- for (var i = 0; i < 20000; ++i) {
- injector.get(D_KEY);
- injector.get(E_KEY);
- }
-}
-
-class A {
- constructor() {
- count++;
- }
-}
-
-class B {
- constructor(a:A) {
- count++;
- }
-}
-
-class C {
- constructor(b:B) {
- count++;
- }
-}
-
-class D {
- constructor(c:C, b:B) {
- count++;
- }
-}
-
-class E {
- constructor(d:D, c:C) {
- count++;
- }
-}
diff --git a/modules/benchmarks/src/di/injector_get_child_benchmark.js b/modules/benchmarks/src/di/injector_get_child_benchmark.js
deleted file mode 100644
index 1aa1195695..0000000000
--- a/modules/benchmarks/src/di/injector_get_child_benchmark.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import {Injector, Key} from "di/di";
-
-var count = 0;
-
-export function run () {
- var bindings = [A, B, C, D, E];
- var injector = new Injector(bindings);
- var childInjector = injector.
- createChild([]).
- createChild([]).
- createChild([]).
- createChild([]).
- createChild([]);
-
- for (var i = 0; i < 20000; ++i) {
- childInjector.get(D);
- childInjector.get(E);
- }
-}
-
-class A {
- constructor() {
- count++;
- }
-}
-
-class B {
- constructor(a:A) {
- count++;
- }
-}
-
-class C {
- constructor(b:B) {
- count++;
- }
-}
-
-class D {
- constructor(c:C, b:B) {
- count++;
- }
-}
-
-class E {
- constructor(d:D, c:C) {
- count++;
- }
-}
diff --git a/modules/benchmarks/src/di/injector_instantiate_benchmark.js b/modules/benchmarks/src/di/injector_instantiate_benchmark.js
deleted file mode 100644
index 9a8d44875f..0000000000
--- a/modules/benchmarks/src/di/injector_instantiate_benchmark.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import {Injector, Key} from "di/di";
-
-var count = 0;
-
-export function run () {
- var bindings = [A, B, C, D];
- var injector = new Injector(bindings);
-
- for (var i = 0; i < 1000; ++i) {
- var child = injector.createChild([E]);
- child.get(E);
- }
-}
-
-class A {
- constructor() {
- count++;
- }
-}
-
-class B {
- constructor(a:A) {
- count++;
- }
-}
-
-class C {
- constructor(b:B) {
- count++;
- }
-}
-
-class D {
- constructor(c:C, b:B) {
- count++;
- }
-}
-
-class E {
- constructor(d:D, c:C) {
- count++;
- }
-}
diff --git a/modules/benchmarks/src/di/main.html b/modules/benchmarks/src/di/main.html
deleted file mode 100644
index 3995f8ae30..0000000000
--- a/modules/benchmarks/src/di/main.html
+++ /dev/null
@@ -1 +0,0 @@
-$SCRIPTS$
\ No newline at end of file
diff --git a/modules/benchmarks/src/di/main.js b/modules/benchmarks/src/di/main.js
deleted file mode 100644
index dac1fc9a9f..0000000000
--- a/modules/benchmarks/src/di/main.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as injector_get_benchmark from './injector_get_benchmark';
-import * as injector_get_by_key_benchmark from './injector_get_by_key_benchmark';
-import * as injector_get_child_benchmark from './injector_get_child_benchmark';
-import * as injector_instantiate_benchmark from './injector_instantiate_benchmark';
-
-import {benchmark, benchmarkStep} from 'benchpress/benchpress';
-
-export function main() {
- benchmark(`Injector.get (token)`, function() {
- benchmarkStep('run', injector_get_benchmark.run);
- });
-
- benchmark(`Injector.get (key)`, function() {
- benchmarkStep('run', injector_get_by_key_benchmark.run);
- });
-
- benchmark(`Injector.get (grand x 5 child)`, function() {
- benchmarkStep('run', injector_get_child_benchmark.run);
- });
-
- benchmark(`Injector.instantiate`, function() {
- benchmarkStep('run', injector_instantiate_benchmark.run);
- });
-}
diff --git a/modules/benchmarks/src/element_injector/element_injector_benchmark.html b/modules/benchmarks/src/element_injector/element_injector_benchmark.html
new file mode 100644
index 0000000000..fb6fdb6ade
--- /dev/null
+++ b/modules/benchmarks/src/element_injector/element_injector_benchmark.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+$SCRIPTS$
+
+
diff --git a/modules/benchmarks/src/element_injector/element_injector_benchmark.js b/modules/benchmarks/src/element_injector/element_injector_benchmark.js
new file mode 100644
index 0000000000..f35218db38
--- /dev/null
+++ b/modules/benchmarks/src/element_injector/element_injector_benchmark.js
@@ -0,0 +1,69 @@
+import {reflector} from 'reflection/reflection';
+import {Injector} from 'di/di';
+import {ProtoElementInjector} from 'core/compiler/element_injector';
+import {document, DOM} from 'facade/dom';
+
+var count = 0;
+var ITERATIONS = 20000;
+
+function setupReflector() {
+ reflector.registerType(A, {
+ 'factory': () => new A(),
+ 'parameters': [],
+ 'annotations' : []
+ });
+ reflector.registerType(B, {
+ 'factory': () => new B(),
+ 'parameters': [],
+ 'annotations' : []
+ });
+ reflector.registerType(C, {
+ 'factory': (a,b) => new C(a,b),
+ 'parameters': [[A],[B]],
+ 'annotations' : []
+ });
+}
+
+export function main() {
+ setupReflector();
+ var appInjector = new Injector([]);
+
+ var bindings = [A, B, C];
+ var proto = new ProtoElementInjector(null, 0, bindings);
+ var elementInjector = proto.instantiate(null,null);
+
+ function instantiate (_) {
+ for (var i = 0; i < ITERATIONS; ++i) {
+ var ei = proto.instantiate(null, null);
+ ei.instantiateDirectives(appInjector, null, null);
+ }
+ }
+
+ function instantiateDirectives (_) {
+ for (var i = 0; i < ITERATIONS; ++i) {
+ elementInjector.clearDirectives();
+ elementInjector.instantiateDirectives(appInjector, null, null);
+ }
+ }
+
+ DOM.on(DOM.querySelector(document, '#instantiate'), 'click', instantiate);
+ DOM.on(DOM.querySelector(document, '#instantiateDirectives'), 'click', instantiateDirectives);
+}
+
+class A {
+ constructor() {
+ count++;
+ }
+}
+
+class B {
+ constructor() {
+ count++;
+ }
+}
+
+class C {
+ constructor(a:A, b:B) {
+ count++;
+ }
+}
diff --git a/modules/benchmarks/src/element_injector/instantiate_benchmark.js b/modules/benchmarks/src/element_injector/instantiate_benchmark.js
deleted file mode 100644
index c034986e9c..0000000000
--- a/modules/benchmarks/src/element_injector/instantiate_benchmark.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import {Injector} from 'di/di';
-import {ProtoElementInjector} from 'core/compiler/element_injector';
-
-var ITERATIONS = 20000;
-var count = 0;
-
-export function run () {
- var appInjector = new Injector([]);
-
- var bindings = [A, B, C];
- var proto = new ProtoElementInjector(null, 0, bindings);
- for (var i = 0; i < ITERATIONS; ++i) {
- var ei = proto.instantiate(null, null);
- ei.instantiateDirectives(appInjector, null, null);
- }
-}
-
-class A {
- constructor() {
- count++;
- }
-}
-
-class B {
- constructor() {
- count++;
- }
-}
-
-class C {
- constructor(a:A, b:B) {
- count++;
- }
-}
diff --git a/modules/benchmarks/src/element_injector/instantiate_benchmark_codegen.js b/modules/benchmarks/src/element_injector/instantiate_benchmark_codegen.js
deleted file mode 100644
index c92fbc092f..0000000000
--- a/modules/benchmarks/src/element_injector/instantiate_benchmark_codegen.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import {Binding, Dependency, Key, Injector} from 'di/di';
-import {ProtoElementInjector} from 'core/compiler/element_injector';
-
-var ITERATIONS = 20000;
-var count = 0;
-
-export function run () {
- var appInjector = new Injector([]);
-
- var bindings = [
- new Binding(Key.get(A), () => new A(), [], false),
- new Binding(Key.get(B), () => new B(), [], false),
- new Binding(Key.get(C), (a,b) => new C(a,b), [
- new Dependency(Key.get(A), false, false, []),
- new Dependency(Key.get(B), false, false, [])
- ], false)];
-
-
- var proto = new ProtoElementInjector(null, 0, bindings);
- for (var i = 0; i < ITERATIONS; ++i) {
- var ei = proto.instantiate(null,null);
- ei.instantiateDirectives(appInjector, null, null);
- }
-}
-
-class A {
- constructor() {
- count++;
- }
-}
-
-class B {
- constructor() {
- count++;
- }
-}
-
-class C {
- constructor(a:A, b:B) {
- count++;
- }
-}
diff --git a/modules/benchmarks/src/element_injector/instantiate_directive_benchmark.js b/modules/benchmarks/src/element_injector/instantiate_directive_benchmark.js
deleted file mode 100644
index e9d3b06b99..0000000000
--- a/modules/benchmarks/src/element_injector/instantiate_directive_benchmark.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import {Injector} from 'di/di';
-import {ProtoElementInjector} from 'core/compiler/element_injector';
-
-var ITERATIONS = 20000;
-var count = 0;
-
-export function run () {
- var appInjector = new Injector([]);
-
- var bindings = [A, B, C];
- var proto = new ProtoElementInjector(null, 0, bindings);
- var ei = proto.instantiate(null,null);
-
- for (var i = 0; i < ITERATIONS; ++i) {
- ei.clearDirectives();
- ei.instantiateDirectives(appInjector, null, null);
- }
-}
-
-class A {
- constructor() {
- count++;
- }
-}
-
-class B {
- constructor() {
- count++;
- }
-}
-
-class C {
- constructor(a:A, b:B) {
- count++;
- }
-}
diff --git a/modules/benchmarks/src/element_injector/main.html b/modules/benchmarks/src/element_injector/main.html
deleted file mode 100644
index 3995f8ae30..0000000000
--- a/modules/benchmarks/src/element_injector/main.html
+++ /dev/null
@@ -1 +0,0 @@
-$SCRIPTS$
\ No newline at end of file
diff --git a/modules/benchmarks/src/element_injector/main.js b/modules/benchmarks/src/element_injector/main.js
deleted file mode 100644
index ebfe18b11d..0000000000
--- a/modules/benchmarks/src/element_injector/main.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import * as instantiate_benchmark from './instantiate_benchmark';
-import * as instantiate_directive_benchmark from './instantiate_directive_benchmark';
-import * as instantiate_benchmark_codegen from './instantiate_benchmark_codegen';
-
-import {benchmark, benchmarkStep} from 'benchpress/benchpress';
-
-export function main() {
- benchmark(`ElementInjector.instantiate + instantiateDirectives`, function() {
- benchmarkStep('run', instantiate_benchmark.run);
- });
-
- benchmark(`ElementInjector.instantiateDirectives`, function() {
- benchmarkStep('run', instantiate_directive_benchmark.run);
- });
-
- benchmark(`ElementInjector.instantiate + instantiateDirectives (codegen)`, function() {
- benchmarkStep('run', instantiate_benchmark_codegen.run);
- });
-}
diff --git a/modules/benchmarks/src/index.html b/modules/benchmarks/src/index.html
new file mode 100644
index 0000000000..9af6c61036
--- /dev/null
+++ b/modules/benchmarks/src/index.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
diff --git a/modules/benchmarks/src/tree/main.html b/modules/benchmarks/src/tree/main.html
deleted file mode 100644
index dd294aa7ef..0000000000
--- a/modules/benchmarks/src/tree/main.html
+++ /dev/null
@@ -1,5 +0,0 @@
-$SCRIPTS$
-
-
-
-
\ No newline at end of file
diff --git a/modules/benchmarks/src/tree/main.js b/modules/benchmarks/src/tree/main.js
deleted file mode 100644
index f98bafc9a3..0000000000
--- a/modules/benchmarks/src/tree/main.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import * as tree_benchmark from './tree_benchmark';
-
-export function main() {
- tree_benchmark.main();
-}
diff --git a/modules/benchmarks/src/tree/tree_benchmark.html b/modules/benchmarks/src/tree/tree_benchmark.html
new file mode 100644
index 0000000000..a0634dd2e3
--- /dev/null
+++ b/modules/benchmarks/src/tree/tree_benchmark.html
@@ -0,0 +1,27 @@
+
+
+
+
+Angular2 tree benchmark
+
+
+
+
+
+Baseline tree benchmark
+
+
+
+
+
+
+
+
+
+
+
+$SCRIPTS$
+
+
\ No newline at end of file
diff --git a/modules/benchmarks/src/tree/tree_benchmark.js b/modules/benchmarks/src/tree/tree_benchmark.js
index 7d54ab3131..526489793d 100644
--- a/modules/benchmarks/src/tree/tree_benchmark.js
+++ b/modules/benchmarks/src/tree/tree_benchmark.js
@@ -1,5 +1,3 @@
-import {benchmark, benchmarkStep} from 'benchpress/benchpress';
-
import {ChangeDetector} from 'change_detection/change_detector';
import {Parser} from 'change_detection/parser/parser';
import {Lexer} from 'change_detection/parser/lexer';
@@ -9,6 +7,7 @@ import {bootstrap, Component, Template, TemplateConfig, ViewPort, Compiler} from
import {CompilerCache} from 'core/compiler/compiler';
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
import {TemplateLoader} from 'core/compiler/template_loader';
+import {LifeCycle} from 'core/life_cycle/life_cycle';
import {reflector} from 'reflection/reflection';
import {DOM, document, Element} from 'facade/dom';
@@ -16,7 +15,7 @@ import {isPresent} from 'facade/lang';
var MAX_DEPTH = 9;
-function setup() {
+function setupReflector() {
// TODO: Put the general calls to reflector.register... in a shared file
// as they are needed in all benchmarks...
@@ -98,6 +97,12 @@ function setup() {
'annotations': []
});
+ reflector.registerType(LifeCycle, {
+ "factory": (cd) => new LifeCycle(cd),
+ "parameters": [[ChangeDetector]],
+ "annotations": []
+ });
+
reflector.registerGetters({
'value': (a) => a.value,
@@ -115,61 +120,62 @@ function setup() {
'data': (a,v) => a.data = v,
'ngIf': (a,v) => a.ngIf = v
});
-
- return bootstrap(AppComponent);
}
export function main() {
+ setupReflector();
+
var app;
var changeDetector;
- setup().then((injector) => {
- changeDetector = injector.get(ChangeDetector);
- app = injector.get(AppComponent);
- });
+ var baselineRootTreeComponent;
+ var count = 0;
- benchmark(`tree benchmark`, function() {
- var count = 0;
+ function ng2DestroyDom(_) {
+ // TODO: We need an initial value as otherwise the getter for data.value will fail
+ // --> this should be already caught in change detection!
+ app.initData = new TreeNode('', null, null);
+ changeDetector.detectChanges();
+ }
- benchmarkStep(`destroyDom binary tree of depth ${MAX_DEPTH}`, function() {
- // TODO: We need an initial value as otherwise the getter for data.value will fail
- // --> this should be already caught in change detection!
- app.initData = new TreeNode('', null, null);
- changeDetector.detectChanges();
+ function ng2CreateDom(_) {
+ var values = count++ % 2 == 0 ?
+ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
+ ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
+
+ app.initData = buildTree(MAX_DEPTH, values, 0);
+ changeDetector.detectChanges();
+ }
+
+ function initNg2() {
+ bootstrap(AppComponent).then((injector) => {
+ changeDetector = injector.get(ChangeDetector);
+ app = injector.get(AppComponent);
+ DOM.on(DOM.querySelector(document, '#ng2DestroyDom'), 'click', ng2DestroyDom);
+ DOM.on(DOM.querySelector(document, '#ng2CreateDom'), 'click', ng2CreateDom);
});
+ }
- benchmarkStep(`createDom binary tree of depth ${MAX_DEPTH}`, function() {
- var maxDepth = 9;
- var values = count++ % 2 == 0 ?
- ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
- ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
+ function baselineDestroyDom(_) {
+ baselineRootTreeComponent.update(new TreeNode('', null, null));
+ }
- app.initData = buildTree(maxDepth, values, 0);
- changeDetector.detectChanges();
- });
+ function baselineCreateDom(_) {
+ var values = count++ % 2 == 0 ?
+ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
+ ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
- });
+ baselineRootTreeComponent.update(buildTree(MAX_DEPTH, values, 0));
+ }
- benchmark(`baseline tree benchmark`, function() {
- var baselineAppElement = DOM.querySelectorAll(document, 'baseline')[0];
- var rootTreeComponent = new BaseLineTreeComponent();
- DOM.appendChild(baselineAppElement, rootTreeComponent.element);
+ function initBaseline() {
+ baselineRootTreeComponent = new BaseLineTreeComponent();
+ DOM.appendChild(DOM.querySelector(document, 'baseline'), baselineRootTreeComponent.element);
+ DOM.on(DOM.querySelector(document, '#baselineDestroyDom'), 'click', baselineDestroyDom);
+ DOM.on(DOM.querySelector(document, '#baselineCreateDom'), 'click', baselineCreateDom);
+ }
- var count = 0;
-
- benchmarkStep(`destroyDom binary tree of depth ${MAX_DEPTH}`, function() {
- rootTreeComponent.update(new TreeNode('', null, null));
- });
-
- benchmarkStep(`createDom binary tree of depth ${MAX_DEPTH}`, function() {
- var maxDepth = 9;
- var values = count++ % 2 == 0 ?
- ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
- ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
-
- rootTreeComponent.update(buildTree(maxDepth, values, 0));
- });
-
- });
+ initNg2();
+ initBaseline();
}
class TreeNode {
diff --git a/modules/benchmarks/test/perf/change_detection_perf.js b/modules/benchmarks/test/perf/change_detection_perf.js
new file mode 100644
index 0000000000..9dfd487a70
--- /dev/null
+++ b/modules/benchmarks/test/perf/change_detection_perf.js
@@ -0,0 +1,26 @@
+"use strict";
+var util = require('../../../../tools/perf/util.js');
+
+describe('ng2 change detection benchmark', function () {
+
+ var URL = 'benchmarks/web/change_detection/change_detection_benchmark.html';
+
+ afterEach(util.verifyNoErrors);
+
+ it('should log ng stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#ng2DetectChanges'],
+ name: browser.params.lang+'.ng2.changeDetection'
+ });
+ });
+
+ it('should log baseline stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#baselineDetectChanges'],
+ name: browser.params.lang+'.baseline.changeDetection'
+ });
+ });
+
+});
diff --git a/modules/benchmarks/test/perf/compiler_perf.js b/modules/benchmarks/test/perf/compiler_perf.js
new file mode 100644
index 0000000000..f525b0e815
--- /dev/null
+++ b/modules/benchmarks/test/perf/compiler_perf.js
@@ -0,0 +1,26 @@
+"use strict";
+var util = require('../../../../tools/perf/util.js');
+
+describe('ng2 compiler benchmark', function () {
+
+ var URL = 'benchmarks/web/compiler/compiler_benchmark.html';
+
+ afterEach(util.verifyNoErrors);
+
+ it('should log withBindings stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#compileWithBindings'],
+ name: browser.params.lang+'.ng2.compile.withBindings'
+ });
+ });
+
+ it('should log noBindings stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#compileNoBindings'],
+ name: browser.params.lang+'.ng2.compile.noBindings'
+ });
+ });
+
+});
diff --git a/modules/benchmarks/test/perf/di_perf.js b/modules/benchmarks/test/perf/di_perf.js
new file mode 100644
index 0000000000..9d84f44304
--- /dev/null
+++ b/modules/benchmarks/test/perf/di_perf.js
@@ -0,0 +1,42 @@
+"use strict";
+var util = require('../../../../tools/perf/util.js');
+
+describe('ng2 di benchmark', function () {
+
+ var URL = 'benchmarks/web/di/di_benchmark.html';
+
+ afterEach(util.verifyNoErrors);
+
+ it('should log the stats for getByToken', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#getByToken'],
+ name: browser.params.lang+'.ng2.di.getByToken'
+ });
+ });
+
+ it('should log the stats for getByKey', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#getByKey'],
+ name: browser.params.lang+'.ng2.di.getByKey'
+ });
+ });
+
+ it('should log the stats for getChild', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#getChild'],
+ name: browser.params.lang+'.ng2.di.getChild'
+ });
+ });
+
+ it('should log the stats for instantiate', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#instantiate'],
+ name: browser.params.lang+'.ng2.di.instantiate'
+ });
+ });
+
+});
diff --git a/modules/benchmarks/test/perf/element_injector_perf.js b/modules/benchmarks/test/perf/element_injector_perf.js
new file mode 100644
index 0000000000..1702196ae8
--- /dev/null
+++ b/modules/benchmarks/test/perf/element_injector_perf.js
@@ -0,0 +1,26 @@
+"use strict";
+var util = require('../../../../tools/perf/util.js');
+
+describe('ng2 element injector benchmark', function () {
+
+ var URL = 'benchmarks/web/element_injector/element_injector_benchmark.html';
+
+ afterEach(util.verifyNoErrors);
+
+ it('should log the stats for instantiate', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#instantiate'],
+ name: browser.params.lang+'.ng2.elementInjector.instantiate'
+ });
+ });
+
+ it('should log the stats for instantiateDirectives', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#instantiateDirectives'],
+ name: browser.params.lang+'.ng2.elementInjector.instantiateDirectives'
+ });
+ });
+
+});
diff --git a/modules/benchmarks/test/perf/tree_perf.js b/modules/benchmarks/test/perf/tree_perf.js
new file mode 100644
index 0000000000..41be46c751
--- /dev/null
+++ b/modules/benchmarks/test/perf/tree_perf.js
@@ -0,0 +1,26 @@
+"use strict";
+var util = require('../../../../tools/perf/util.js');
+
+describe('ng2 tree benchmark', function () {
+
+ var URL = 'benchmarks/web/tree/tree_benchmark.html';
+
+ afterEach(util.verifyNoErrors);
+
+ it('should log the ng stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#ng2DestroyDom', '#ng2CreateDom'],
+ name: browser.params.lang+'.ng2.tree'
+ });
+ });
+
+ it('should log the baseline stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#baselineDestroyDom', '#baselineCreateDom'],
+ name: browser.params.lang+'.baseline.tree'
+ });
+ });
+
+});
diff --git a/modules/benchmarks_external/pubspec.yaml b/modules/benchmarks_external/pubspec.yaml
index 41e80a792a..132b08601b 100644
--- a/modules/benchmarks_external/pubspec.yaml
+++ b/modules/benchmarks_external/pubspec.yaml
@@ -3,7 +3,6 @@ environment:
sdk: '>=1.4.0'
dependencies:
angular: ">=1.0.0 <2.0.0"
- benchpress:
- path: ../benchpress
+ browser: '>=0.10.0 <0.11.0'
transformers:
- angular
\ No newline at end of file
diff --git a/modules/benchmarks_external/src/compiler/compiler_benchmark_ng10.dart b/modules/benchmarks_external/src/compiler/compiler_benchmark.dart
similarity index 54%
rename from modules/benchmarks_external/src/compiler/compiler_benchmark_ng10.dart
rename to modules/benchmarks_external/src/compiler/compiler_benchmark.dart
index 834855c792..db03be93c9 100644
--- a/modules/benchmarks_external/src/compiler/compiler_benchmark_ng10.dart
+++ b/modules/benchmarks_external/src/compiler/compiler_benchmark.dart
@@ -1,8 +1,8 @@
+// compiler benchmark in AngularDart 1.x
library compiler_benchmark_ng10;
import 'package:angular/angular.dart';
import 'package:angular/application_factory.dart';
-import 'package:benchpress/benchpress.dart';
import 'dart:html';
var COUNT = 30;
@@ -16,42 +16,26 @@ main() {
..bind(Dir3)
..bind(Dir4);
- benchmark("AngularDart 1.0 Compiler.compile 5*${COUNT} element with bindings", () {
- var template = loadTemplate('templateWithBindings', COUNT);
+ var templateWithBindings = loadTemplate('templateWithBindings', COUNT);
+ var templateNoBindings = loadTemplate('templateWithBindings', COUNT);
- final injector = applicationFactory().addModule(m).run();
+ final injector = applicationFactory().addModule(m).run();
+ final compiler = injector.get(Compiler);
+ final directiveMap = injector.get(DirectiveMap);
- final compiler = injector.get(Compiler);
- final directiveMap = injector.get(DirectiveMap);
- final di = injector.get(DirectiveInjector);
- final rootScope = injector.get(Scope);
+ compileWithBindings(_) {
+ final cloned = templateWithBindings.clone(true);
+ compiler([cloned], directiveMap);
+ }
- benchmarkStep('run', () {
- final cloned = template.clone(true);
- final scope = rootScope.createChild({});
- final viewFactory = compiler([cloned], directiveMap);
- viewFactory(scope, di);
- scope.destroy();
- });
- });
+ compileNoBindings(_) {
+ final cloned = templateNoBindings.clone(true);
+ compiler([cloned], directiveMap);
+ }
- benchmark("AngularDart 1.0 instantiate 5*${COUNT} element with bindings", () {
- var template = loadTemplate('templateWithBindings', COUNT);
+ document.querySelector('#compileWithBindings').addEventListener('click', compileWithBindings);
+ document.querySelector('#compileNoBindings').addEventListener('click', compileNoBindings);
- final injector = applicationFactory().addModule(m).run();
-
- final compiler = injector.get(Compiler);
- final directiveMap = injector.get(DirectiveMap);
- final di = injector.get(DirectiveInjector);
- final rootScope = injector.get(Scope);
- final viewFactory = compiler([template], directiveMap);
-
- benchmarkStep('run', () {
- var scope = rootScope.createChild({});
- viewFactory(scope, di);
- scope.destroy();
- });
- });
}
loadTemplate(templateId, repeatCount) {
diff --git a/modules/benchmarks_external/src/compiler/compiler_benchmark_ng13.es6 b/modules/benchmarks_external/src/compiler/compiler_benchmark.es6
similarity index 51%
rename from modules/benchmarks_external/src/compiler/compiler_benchmark_ng13.es6
rename to modules/benchmarks_external/src/compiler/compiler_benchmark.es6
index 895d0b5399..15ce5ee3f0 100644
--- a/modules/benchmarks_external/src/compiler/compiler_benchmark_ng13.es6
+++ b/modules/benchmarks_external/src/compiler/compiler_benchmark.es6
@@ -1,46 +1,7 @@
-import {benchmark, benchmarkStep} from 'benchpress/benchpress';
-
+// compiler benchmark in AngularJS 1.x
var COUNT = 30;
-var $compile;
-var $rootScope;
export function main() {
-
- benchmark(`Ng 1.3 Compiler.compile 5*${COUNT} element no bindings`, function() {
- var template = loadTemplate('templateNoBindings', COUNT);
-
- benchmarkStep('run', function() {
- // Need to clone every time as the compiler might modify the template!
- var cloned = template.cloneNode(true);
- $compile(cloned);
- });
- });
-
- benchmark(`Ng 1.3 Compiler.compile 5*${COUNT} element with bindings`, function() {
- var template = loadTemplate('templateWithBindings', COUNT);
-
- benchmarkStep('run', function() {
- // Need to clone every time as the compiler might modify the template!
- var cloned = template.cloneNode(true);
- $compile(cloned);
- });
- });
-
- benchmark(`Ng 1.3 instantiate 5*${COUNT} element with bindings`, function() {
- var linkFn;
-
- setTimeout(function() {
- var template = loadTemplate('templateWithBindings', COUNT);
- linkFn = $compile(template);
- });
-
- benchmarkStep('run', function() {
- var scope = $rootScope.$new();
- linkFn(scope);
- scope.$destroy();
- });
- });
-
var ngEl = document.createElement('div');
angular.bootstrap(ngEl, ['app']);
}
@@ -62,7 +23,7 @@ function loadTemplate(templateId, repeatCount) {
}
angular.module('app', [])
-.directive('dir0', function($parse) {
+.directive('dir0', ['$parse', function($parse) {
return {
compile: function($element, $attrs) {
var expr = $parse($attrs.attr0);
@@ -71,8 +32,8 @@ angular.module('app', [])
}
}
};
-})
-.directive('dir1', function($parse) {
+}])
+.directive('dir1', ['$parse', function($parse) {
return {
compile: function($element, $attrs) {
var expr = $parse($attrs.attr1);
@@ -81,8 +42,8 @@ angular.module('app', [])
}
}
};
-})
-.directive('dir2', function($parse) {
+}])
+.directive('dir2', ['$parse', function($parse) {
return {
compile: function($element, $attrs) {
var expr = $parse($attrs.attr2);
@@ -91,8 +52,8 @@ angular.module('app', [])
}
}
};
-})
-.directive('dir3', function($parse) {
+}])
+.directive('dir3', ['$parse', function($parse) {
return {
compile: function($element, $attrs) {
var expr = $parse($attrs.attr3);
@@ -101,8 +62,8 @@ angular.module('app', [])
}
}
};
-})
-.directive('dir4', function($parse) {
+}])
+.directive('dir4', ['$parse', function($parse) {
return {
compile: function($element, $attrs) {
var expr = $parse($attrs.attr4);
@@ -111,9 +72,24 @@ angular.module('app', [])
}
}
};
-})
-.run(function(_$compile_, _$rootScope_) {
- $compile = _$compile_;
- $rootScope = _$rootScope_;
-});
+}])
+.run(['$compile', function($compile) {
+ var templateNoBindings = loadTemplate('templateNoBindings', COUNT);
+ var templateWithBindings = loadTemplate('templateWithBindings', COUNT);
+
+ document.querySelector('#compileWithBindings').addEventListener('click', compileWithBindings, false);
+ document.querySelector('#compileNoBindings').addEventListener('click', compileNoBindings, false);
+
+ function compileNoBindings(_) {
+ // Need to clone every time as the compiler might modify the template!
+ var cloned = templateNoBindings.cloneNode(true);
+ $compile(cloned);
+ }
+
+ function compileWithBindings(_) {
+ // Need to clone every time as the compiler might modify the template!
+ var cloned = templateWithBindings.cloneNode(true);
+ $compile(cloned);
+ }
+}]);
diff --git a/modules/benchmarks_external/src/compiler/main.html b/modules/benchmarks_external/src/compiler/compiler_benchmark.html
similarity index 92%
rename from modules/benchmarks_external/src/compiler/main.html
rename to modules/benchmarks_external/src/compiler/compiler_benchmark.html
index 178588bd7d..460bb9bf54 100644
--- a/modules/benchmarks_external/src/compiler/main.html
+++ b/modules/benchmarks_external/src/compiler/compiler_benchmark.html
@@ -1,4 +1,9 @@
-$SCRIPTS$
+
+
+
+
+
+
@@ -30,3 +35,8 @@ $SCRIPTS$
+
+$SCRIPTS$
+
+
+
\ No newline at end of file
diff --git a/modules/benchmarks_external/src/compiler/main.dart b/modules/benchmarks_external/src/compiler/main.dart
deleted file mode 100644
index 8c6ceb28a2..0000000000
--- a/modules/benchmarks_external/src/compiler/main.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-library compiler_benchmark;
-
-import './compiler_benchmark_ng10.dart' as cbm;
-
-main () {
- cbm.main();
-}
\ No newline at end of file
diff --git a/modules/benchmarks_external/src/compiler/main.es6 b/modules/benchmarks_external/src/compiler/main.es6
deleted file mode 100644
index a127b6e36b..0000000000
--- a/modules/benchmarks_external/src/compiler/main.es6
+++ /dev/null
@@ -1 +0,0 @@
-export {main} from './compiler_benchmark_ng13';
diff --git a/modules/benchmarks_external/src/index.html b/modules/benchmarks_external/src/index.html
new file mode 100644
index 0000000000..51a492c9da
--- /dev/null
+++ b/modules/benchmarks_external/src/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/modules/benchmarks_external/src/tree/main.dart b/modules/benchmarks_external/src/tree/main.dart
deleted file mode 100644
index 59d88c0aee..0000000000
--- a/modules/benchmarks_external/src/tree/main.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-library tree_benchmark;
-
-import './tree_benchmark_ng10.dart' as bm;
-
-main () {
- bm.main();
-}
\ No newline at end of file
diff --git a/modules/benchmarks_external/src/tree/main.es6 b/modules/benchmarks_external/src/tree/main.es6
deleted file mode 100644
index c064dd1dbb..0000000000
--- a/modules/benchmarks_external/src/tree/main.es6
+++ /dev/null
@@ -1 +0,0 @@
-export {main} from './tree_benchmark_ng13';
diff --git a/modules/benchmarks_external/src/tree/main.html b/modules/benchmarks_external/src/tree/main.html
deleted file mode 100644
index a260a6be0f..0000000000
--- a/modules/benchmarks_external/src/tree/main.html
+++ /dev/null
@@ -1,3 +0,0 @@
-$SCRIPTS$
-
-
\ No newline at end of file
diff --git a/modules/benchmarks_external/src/tree/tree_benchmark_ng10.dart b/modules/benchmarks_external/src/tree/tree_benchmark.dart
similarity index 65%
rename from modules/benchmarks_external/src/tree/tree_benchmark_ng10.dart
rename to modules/benchmarks_external/src/tree/tree_benchmark.dart
index 44a651e4dd..e81408b0d1 100644
--- a/modules/benchmarks_external/src/tree/tree_benchmark_ng10.dart
+++ b/modules/benchmarks_external/src/tree/tree_benchmark.dart
@@ -1,8 +1,8 @@
+// tree benchmark in AngularDart 1.x
library tree_benchmark_ng10;
import 'package:angular/angular.dart';
import 'package:angular/application_factory.dart';
-import 'package:benchpress/benchpress.dart';
import 'dart:html';
var MAX_DEPTH = 9;
@@ -23,28 +23,26 @@ main() {
final injector = setup();
final zone = injector.get(VmTurnZone);
final rootScope = injector.get(Scope);
+ var count = 0;
- benchmark("tree benchmark", () {
- var count = 0;
-
- benchmarkStep("AngularDart destroyDom binary tree of depth ${MAX_DEPTH}", () {
- zone.run(() {
- rootScope.context['initData'] = new TreeNode('');
- });
+ destroyDom(_) {
+ zone.run(() {
+ rootScope.context['initData'] = new TreeNode('');
});
+ }
- benchmarkStep("AngularDart createDom binary tree of depth ${MAX_DEPTH}", () {
- zone.run(() {
- var maxDepth = 9;
- var values = count++ % 2 == 0 ?
- ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
- ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
+ createDom(_) {
+ zone.run(() {
+ var values = count++ % 2 == 0 ?
+ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
+ ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
- rootScope.context['initData'] = buildTree(maxDepth, values, 0);
- });
+ rootScope.context['initData'] = buildTree(MAX_DEPTH, values, 0);
});
+ }
- });
+ document.querySelector('#destroyDom').addEventListener('click', destroyDom);
+ document.querySelector('#createDom').addEventListener('click', createDom);
}
@Component(
diff --git a/modules/benchmarks_external/src/tree/tree_benchmark.es6 b/modules/benchmarks_external/src/tree/tree_benchmark.es6
new file mode 100644
index 0000000000..8d8177a38e
--- /dev/null
+++ b/modules/benchmarks_external/src/tree/tree_benchmark.es6
@@ -0,0 +1,102 @@
+// tree benchmark in AngularJS 1.x
+var MAX_DEPTH = 9;
+
+export function main() {
+ angular.bootstrap(document.body, ['app']);
+}
+
+angular.module('app', [])
+.directive('tree', function() {
+ return {
+ scope: {
+ data: '='
+ },
+ template:
+' {{data.value}}'+
+' '+
+' '+
+''
+ };
+})
+// special directive for "if" as angular 1.3 does not support
+// recursive components.
+.directive('treeIf', ['$compile', '$parse', function($compile, $parse) {
+ var transcludeFn;
+ return {
+ compile: function(element, attrs) {
+ var expr = $parse(attrs.treeIf);
+ var template = '';
+ var transclude;
+ return function($scope, $element, $attrs) {
+ if (!transclude) {
+ transclude = $compile(template);
+ }
+ var childScope;
+ var childElement;
+ $scope.$watch(expr, function(newValue) {
+ if (childScope) {
+ childScope.$destroy();
+ childElement.remove();
+ childScope = null;
+ childElement = null;
+ }
+ if (newValue) {
+ childScope = $scope.$new();
+ childElement = transclude(childScope, function(clone) {
+ $element.append(clone);
+ });
+ }
+ });
+ }
+
+ }
+ }
+}])
+.config(['$compileProvider', function($compileProvider) {
+ $compileProvider.debugInfoEnabled(false);
+}])
+.run(['$rootScope', function($rootScope) {
+ var count = 0;
+
+ document.querySelector('#destroyDom').addEventListener('click', destroyDom, false);
+ document.querySelector('#createDom').addEventListener('click', createDom, false);
+
+ function destroyDom(_) {
+ $rootScope.$apply(function() {
+ $rootScope.initData = new TreeNode('', null, null);
+ });
+ }
+
+ function createDom(_) {
+ var maxDepth = MAX_DEPTH;
+ var values = count++ % 2 == 0 ?
+ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
+ ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
+
+ $rootScope.$apply(function() {
+ $rootScope.initData = buildTree(MAX_DEPTH, values, 0);
+ });
+ }
+}]);
+
+class TreeNode {
+ value:string;
+ left:TreeNode;
+ right:TreeNode;
+ constructor(value, left, right) {
+ this.value = value;
+ this.left = left;
+ this.right = right;
+ }
+}
+
+function buildTree(maxDepth, values, curDepth) {
+ if (maxDepth === curDepth) return new TreeNode('', null, null);
+ return new TreeNode(
+ values[curDepth],
+ buildTree(maxDepth, values, curDepth+1),
+ buildTree(maxDepth, values, curDepth+1));
+}
+
+
+
diff --git a/modules/benchmarks_external/src/tree/tree_benchmark.html b/modules/benchmarks_external/src/tree/tree_benchmark.html
new file mode 100644
index 0000000000..5d381f83ae
--- /dev/null
+++ b/modules/benchmarks_external/src/tree/tree_benchmark.html
@@ -0,0 +1,17 @@
+
+
+
+
+AngularJS/Dart 1.x tree benchmark
+
+
+
+
+
+
+
+
+
+$SCRIPTS$
+
+
\ No newline at end of file
diff --git a/modules/benchmarks_external/src/tree/tree_benchmark_ng13.es6 b/modules/benchmarks_external/src/tree/tree_benchmark_ng13.es6
deleted file mode 100644
index 9dd2c8af11..0000000000
--- a/modules/benchmarks_external/src/tree/tree_benchmark_ng13.es6
+++ /dev/null
@@ -1,112 +0,0 @@
-import {benchmark, benchmarkStep} from 'benchpress/benchpress';
-
-var MAX_DEPTH = 9;
-
-function setup() {
- var $rootScope;
-
- angular.module('app', [])
- .directive('tree', function() {
- return {
- scope: {
- data: '='
- },
- template:
-' {{data.value}}'+
-' '+
-' '+
-''
- };
- })
- // special directive for "if" as angular 1.3 does not support
- // recursive components.
- .directive('treeIf', ['$compile', '$parse', function($compile, $parse) {
- var transcludeFn;
- return {
- compile: function(element, attrs) {
- var expr = $parse(attrs.treeIf);
- var template = '';
- var transclude;
- return function($scope, $element, $attrs) {
- if (!transclude) {
- transclude = $compile(template);
- }
- var childScope;
- var childElement;
- $scope.$watch(expr, function(newValue) {
- if (childScope) {
- childScope.$destroy();
- childElement.remove();
- childScope = null;
- childElement = null;
- }
- if (newValue) {
- childScope = $scope.$new();
- childElement = transclude(childScope, function(clone) {
- $element.append(clone);
- });
- }
- });
- }
-
- }
- }
- }])
- .config(['$compileProvider', function($compileProvider) {
- $compileProvider.debugInfoEnabled(false);
- }])
- .run(['$rootScope', function(_$rootScope_) {
- $rootScope = _$rootScope_;
- }])
- angular.bootstrap(document.body, ['app']);
- return $rootScope;
-}
-
-export function main() {
- var $rootScope = setup();
-
- benchmark(`tree benchmark`, function() {
- var count = 0;
-
- benchmarkStep(`AngularJS destroyDom binary tree of depth ${MAX_DEPTH}`, function() {
- $rootScope.$apply(function() {
- $rootScope.initData = new TreeNode('', null, null);
- });
- });
-
- benchmarkStep(`AngularJS createDom binary tree of depth ${MAX_DEPTH}`, function() {
- var maxDepth = 9;
- var values = count++ % 2 == 0 ?
- ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*'] :
- ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', '-'];
-
- $rootScope.$apply(function() {
- $rootScope.initData = buildTree(maxDepth, values, 0);
- });
- });
-
- });
-
-}
-
-class TreeNode {
- value:string;
- left:TreeNode;
- right:TreeNode;
- constructor(value, left, right) {
- this.value = value;
- this.left = left;
- this.right = right;
- }
-}
-
-function buildTree(maxDepth, values, curDepth) {
- if (maxDepth === curDepth) return new TreeNode('', null, null);
- return new TreeNode(
- values[curDepth],
- buildTree(maxDepth, values, curDepth+1),
- buildTree(maxDepth, values, curDepth+1));
-}
-
-
-
diff --git a/modules/benchmarks_external/test/perf/compiler_perf.js b/modules/benchmarks_external/test/perf/compiler_perf.js
new file mode 100644
index 0000000000..f2be62cca0
--- /dev/null
+++ b/modules/benchmarks_external/test/perf/compiler_perf.js
@@ -0,0 +1,26 @@
+"use strict";
+var util = require('../../../../tools/perf/util.js');
+
+describe('ng1.x compiler benchmark', function () {
+
+ var URL = 'benchmarks_external/web/compiler/compiler_benchmark.html';
+
+ afterEach(util.verifyNoErrors);
+
+ it('should log withBinding stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#compileWithBindings'],
+ name: browser.params.lang+'.ng1.compile.withBindings'
+ });
+ });
+
+ it('should log noBindings stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#compileNoBindings'],
+ name: browser.params.lang+'.ng1.compile.noBindings'
+ });
+ });
+
+});
diff --git a/modules/benchmarks_external/test/perf/tree_perf.js b/modules/benchmarks_external/test/perf/tree_perf.js
new file mode 100644
index 0000000000..915cf53cfe
--- /dev/null
+++ b/modules/benchmarks_external/test/perf/tree_perf.js
@@ -0,0 +1,18 @@
+"use strict";
+var util = require('../../../../tools/perf/util.js');
+
+describe('ng1.x tree benchmark', function () {
+
+ var URL = 'benchmarks_external/web/tree/tree_benchmark.html';
+
+ afterEach(util.verifyNoErrors);
+
+ it('should log the stats', function() {
+ util.runSimpleBenchmark({
+ url: URL,
+ buttons: ['#destroyDom', '#createDom'],
+ name: browser.params.lang+'.ng1.tree'
+ });
+ });
+
+});
diff --git a/modules/benchpress/pubspec.yaml b/modules/benchpress/pubspec.yaml
deleted file mode 100644
index b83af2da19..0000000000
--- a/modules/benchpress/pubspec.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-name: benchpress
-environment:
- sdk: '>=1.4.0'
-dependencies:
diff --git a/modules/benchpress/src/benchpress.dart b/modules/benchpress/src/benchpress.dart
deleted file mode 100644
index 81542709bd..0000000000
--- a/modules/benchpress/src/benchpress.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-library benchmarks.benchpress;
-
-import 'dart:js' as js;
-import 'dart:html';
-import 'dart:async';
-
-// TODO: move the functionality of this module into benchpress and replace this
-// file with a Dart wrapper!
-
-var _benchmarkNames = [];
-
-_benchmarkId(index) {
- return "benchmark${index}";
-}
-
-_useBenchmark(index) {
- var search = window.location.search;
- if (search.length > 0) {
- search = search.substring(1);
- }
- if (search.length > 0) {
- return search == _benchmarkId(index);
- } else {
- return true;
- }
-}
-
-_onLoad(callback) {
- var isReady = document.readyState == 'complete';
- if (isReady) {
- Timer.run(callback);
- } else {
- window.addEventListener('load', (event) => callback(), false);
- }
-}
-
-_createBenchmarkMenu() {
- var div = document.createElement('div');
- div.innerHtml += 'Benchmarks:
All';
- for (var i=0; i<_benchmarkNames.length; i++) {
- var activeClass = _useBenchmark(i) ? 'active' : '';
- div.innerHtml += '${_benchmarkNames[i]}';
- }
- document.body.insertBefore(div, document.body.childNodes[0]);
-}
-
-benchmark(name, stepsCreationCallback) {
- _benchmarkNames.add(name);
- if (_benchmarkNames.length == 2) {
- _onLoad(_createBenchmarkMenu);
- }
- if (_useBenchmark(_benchmarkNames.length-1)) {
- stepsCreationCallback();
- }
-}
-
-benchmarkStep(name, callback) {
- var benchmarkName = _benchmarkNames[_benchmarkNames.length-1];
- js.context['benchmarkSteps'].add(new js.JsObject.jsify({
- "name": benchmarkName + '#' + name,
- "fn": new js.JsFunction.withThis((_) => callback())
- }));
-}
diff --git a/modules/benchpress/src/benchpress.es6 b/modules/benchpress/src/benchpress.es6
deleted file mode 100644
index d5e5d5e0df..0000000000
--- a/modules/benchpress/src/benchpress.es6
+++ /dev/null
@@ -1,55 +0,0 @@
-// TODO: move the functionality of this module into benchpress itself!
-
-var benchmarkNames = [];
-
-function benchmarkId(index) {
- return 'benchmark' + index;
-}
-
-function useBenchmark(index) {
- var search = window.location.search;
- if (search.length > 0) {
- search = search.substring(1);
- }
- if (search.length > 0) {
- return search == benchmarkId(index);
- } else {
- return true;
- }
-}
-
-function onLoad(callback) {
- var isReady = document.readyState === 'complete';
- if (isReady) {
- window.setTimeout(callback);
- } else {
- window.addEventListener('load', callback, false);
- }
-}
-
-function createBenchmarkMenu() {
- var div = document.createElement('div');
- div.innerHTML += 'Benchmarks:
All';
- for (var i=0; i'+benchmarkNames[i]+'');
- }
- document.body.insertBefore(div, document.body.childNodes[0]);
-}
-
-export function benchmark(name, stepsCreationCallback) {
- benchmarkNames.push(name);
- if (benchmarkNames.length === 2) {
- onLoad(createBenchmarkMenu);
- }
- if (useBenchmark(benchmarkNames.length-1)) {
- stepsCreationCallback();
- }
-}
-
-export function benchmarkStep(name, callback) {
- var benchmarkName = benchmarkNames[benchmarkNames.length-1];
- window.benchmarkSteps.push({
- name: benchmarkName + '#' + name, fn: callback
- });
-}
diff --git a/modules/core/src/compiler/compiler.js b/modules/core/src/compiler/compiler.js
index 9ab2f6545d..50e82378fa 100644
--- a/modules/core/src/compiler/compiler.js
+++ b/modules/core/src/compiler/compiler.js
@@ -36,6 +36,10 @@ export class CompilerCache {
}
return result;
}
+
+ clear() {
+ this._cache = MapWrapper.create();
+ }
}
/**
diff --git a/package.json b/package.json
index 67757d8dba..3ba814508d 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
"author": "Tobias Bosch ",
"license": "Apache-2.0",
"dependencies": {
- "angular-benchpress": "^0.1.3",
+ "protractor": "1.5.x",
"del": "~1",
"es6-module-loader": "^0.9.2",
"event-stream": "^3.1.5",
diff --git a/protractor-perf-dart2js.conf.js b/protractor-perf-dart2js.conf.js
new file mode 100644
index 0000000000..89176bbbdb
--- /dev/null
+++ b/protractor-perf-dart2js.conf.js
@@ -0,0 +1,3 @@
+var config = exports.config = require('./protractor-perf-shared.js').config;
+config.params.lang = 'dart';
+config.baseUrl = 'http://localhost:8002/';
diff --git a/protractor-perf-js.conf.js b/protractor-perf-js.conf.js
new file mode 100644
index 0000000000..172de8c4d5
--- /dev/null
+++ b/protractor-perf-js.conf.js
@@ -0,0 +1,4 @@
+var config = exports.config = require('./protractor-perf-shared.js').config;
+config.params.lang = 'js';
+config.baseUrl = 'http://localhost:8001/';
+
diff --git a/protractor-perf-shared.js b/protractor-perf-shared.js
new file mode 100644
index 0000000000..6eb78ebc80
--- /dev/null
+++ b/protractor-perf-shared.js
@@ -0,0 +1,50 @@
+var config = exports.config = {
+
+ specs: ['modules/*/test/**/*_perf.js'],
+
+ params: {
+ // number test iterations to warm up the browser
+ warmupCount: 10,
+ // number test iterations to measure
+ measureCount: 10,
+ // TODO(tbosch): remove this and provide a proper protractor integration
+ sleepInterval: process.env.TRAVIS ? 5000 : 1000,
+ },
+
+ // Disable waiting for Angular as we don't have an integration layer yet...
+ // TODO(tbosch): Implement a proper debugging API for Ng2.0, remove this here
+ // and the sleeps in all tests.
+ onPrepare: function() {
+ browser.ignoreSynchronization = true;
+ },
+
+ jasmineNodeOpts: {
+ showColors: true,
+ defaultTimeoutInterval: 30000
+ }
+};
+
+// TODO: add real mobile devices via a cloud provider that supports appium
+if (process.env.TRAVIS) {
+ config.capabilities = {
+ name: 'Dartium',
+ browserName: 'chrome',
+ chromeOptions: {
+ 'binary': process.env.DARTIUM,
+ 'args': ['--js-flags=--expose-gc']
+ },
+ loggingPrefs: {
+ performance: 'ALL'
+ }
+ };
+} else {
+ config.capabilities = {
+ browserName: 'chrome',
+ chromeOptions: {
+ 'args': ['--js-flags=--expose-gc']
+ },
+ loggingPrefs: {
+ performance: 'ALL'
+ }
+ };
+}
\ No newline at end of file
diff --git a/scripts/travis/build.sh b/scripts/travis/build.sh
index 95e817aed3..707c0c6fd0 100755
--- a/scripts/travis/build.sh
+++ b/scripts/travis/build.sh
@@ -1,5 +1,4 @@
#!/bin/bash
-
set -e
echo =============================================================================
@@ -17,4 +16,18 @@ pub install
--browsers=$BROWSERS --single-run
./node_modules/karma/bin/karma start karma-dart.conf \
--reporters=dots \
- --browsers=$BROWSERS --single-run
\ No newline at end of file
+ --browsers=$BROWSERS --single-run
+
+./node_modules/.bin/webdriver-manager update
+
+function killServer () {
+ kill $serverPid
+}
+
+./node_modules/.bin/gulp serve.js.prod serve.js.dart2js&
+serverPid=$!
+
+trap killServer EXIT
+
+./node_modules/.bin/protractor protractor-perf-js.conf.js
+./node_modules/.bin/protractor protractor-perf-dart2js.conf.js
\ No newline at end of file
diff --git a/tools/build/benchpress.js b/tools/build/benchpress.js
deleted file mode 100644
index e0d7a9c84c..0000000000
--- a/tools/build/benchpress.js
+++ /dev/null
@@ -1,39 +0,0 @@
-var util = require('./util');
-var path = require('path');
-var benchpress = require('angular-benchpress/lib/cli');
-var through2 = require('through2');
-var Q = require('q');
-var path = require('path');
-
-module.exports = function(gulp, plugins, config) {
- return function() {
- var benchmarkParentFolders = {};
- var createBpConfStream = util.streamToPromise(
- gulp.src(path.join(config.buildDir, config.mainHtmls))
- .pipe(through2.obj(function(file, enc, done) {
- file.path = path.join(path.dirname(file.path), config.configFile.name);
- file.contents = new Buffer(config.configFile.content);
- this.push(file);
- benchmarkParentFolders[getParentFolder(file.path)] = true;
- done();
- }))
- .pipe(gulp.dest(config.buildDir)));
-
- return createBpConfStream.then(function() {
- return Promise.all(Object.keys(benchmarkParentFolders).map(function(benchmarkParentPath) {
- var defer = Q.defer();
- benchpress.build({
- benchmarksPath: benchmarkParentPath,
- buildPath: path.join(benchmarkParentPath, path.join('../', config.outputFolderName))
- }, defer.makeNodeResolver());
- return defer.promise;
- }));
- });
- };
-};
-
-function getParentFolder(file) {
- var parts = path.dirname(file).split(path.sep);
- parts.pop();
- return parts.join(path.sep);
-}
\ No newline at end of file
diff --git a/tools/build/jsserve.js b/tools/build/jsserve.js
index ab263b9a6a..0a60f5bb8f 100644
--- a/tools/build/jsserve.js
+++ b/tools/build/jsserve.js
@@ -2,7 +2,7 @@ module.exports = function(gulp, plugins, config) {
return function() {
plugins.connect.server({
root: [__dirname+'/../../'+config.path],
- port: 8000,
+ port: config.port,
livereload: false,
open: false
})();
diff --git a/tools/build/pubbuild.js b/tools/build/pubbuild.js
new file mode 100644
index 0000000000..ac51f1e658
--- /dev/null
+++ b/tools/build/pubbuild.js
@@ -0,0 +1,46 @@
+var util = require('./util');
+var Q = require('q');
+var spawn = require('child_process').spawn;
+var through2 = require('through2');
+var path = require('path');
+var glob = require('glob');
+
+module.exports = function(gulp, plugins, config) {
+ return function() {
+ var webFolders = [].slice.call(glob.sync(path.join(config.src, '*/web')));
+ return nextFolder();
+
+ function nextFolder() {
+ if (!webFolders.length) {
+ return;
+ }
+ var folder = getParentFolder(webFolders.shift());
+ var destFolder = path.resolve(path.join(config.dest, path.basename(folder)));
+ return util.processToPromise(spawn(config.command, ['build', '-o', destFolder], {
+ stdio: 'inherit',
+ cwd: folder
+ })).then(function() {
+ return replaceDartWithJsScripts(gulp, destFolder);
+ }).then(nextFolder);
+ }
+ };
+};
+
+function getParentFolder(folder) {
+ var parts = folder.split(path.sep);
+ parts.pop();
+ return parts.join(path.sep);
+}
+
+function replaceDartWithJsScripts(gulp, folder) {
+ return util.streamToPromise(gulp.src(path.join(folder, '**/*.html'))
+ .pipe(through2.obj(function(file, enc, done) {
+ var content = file.contents.toString();
+ content = content.replace(/\.dart/, '.dart.js');
+ content = content.replace(/application\/dart/, 'text/javascript');
+ file.contents = new Buffer(content);
+ this.push(file);
+ done();
+ }))
+ .pipe(gulp.dest(folder)));
+}
\ No newline at end of file
diff --git a/tools/perf/util.js b/tools/perf/util.js
new file mode 100644
index 0000000000..c5c2e01368
--- /dev/null
+++ b/tools/perf/util.js
@@ -0,0 +1,179 @@
+var webdriver = require('protractor/node_modules/selenium-webdriver');
+
+module.exports = {
+ perfLogs: perfLogs,
+ sumTimelineStats: sumTimelineStats,
+ runSimpleBenchmark: runSimpleBenchmark,
+ verifyNoErrors: verifyNoErrors,
+ printObjectAsMarkdown: printObjectAsMarkdown
+};
+
+function perfLogs() {
+ return plainLogs('performance').then(function(entries) {
+ var entriesByMethod = {};
+ entries.forEach(function(entry) {
+ var message = JSON.parse(entry.message).message;
+ var entries = entriesByMethod[message.method];
+ if (!entries) {
+ entries = entriesByMethod[message.method] = [];
+ }
+ entries.push(message.params);
+ });
+ return entriesByMethod;
+ });
+}
+
+// Needed as selenium-webdriver does not forward
+// performance logs in the correct way
+function plainLogs(type) {
+ var webdriver = require('protractor/node_modules/selenium-webdriver');
+ return browser.driver.schedule(
+ new webdriver.Command(webdriver.CommandName.GET_LOG).
+ setParameter('type', type),
+ 'WebDriver.manage().logs().get(' + type + ')');
+};
+
+
+function sumTimelineStats(messages) {
+ var recordStats = {
+ script: 0,
+ gc: {
+ time: 0,
+ amount: 0
+ },
+ render: 0
+ };
+ messages.forEach(function(message) {
+ sumTimelineRecordStats(message.record, recordStats);
+ });
+ return recordStats;
+}
+
+function sumTimelineRecordStats(record, result) {
+ var summedChildrenDuration = 0;
+ if (record.children) {
+ record.children.forEach(function(child) {
+ summedChildrenDuration += sumTimelineRecordStats(child, result);
+ });
+ }
+ // in case a script forced a gc or a reflow
+ // we need to substract the gc time / reflow time
+ // from the script time!
+ var recordDuration = (record.endTime ? record.endTime - record.startTime : 0)
+ - summedChildrenDuration;
+
+ var recordSummed = true;
+ if (record.type === 'FunctionCall') {
+ result.script += recordDuration;
+ } else if (record.type === 'GCEvent') {
+ result.gc.time += recordDuration;
+ result.gc.amount += record.data.usedHeapSizeDelta;
+ } else if (record.type === 'RecalculateStyles' ||
+ record.type === 'Layout' ||
+ record.type === 'UpdateLayerTree' ||
+ record.type === 'Paint' ||
+ record.type === 'Rasterize' ||
+ record.type === 'CompositeLayers') {
+ result.render += recordDuration;
+ } else {
+ recordSummed = false;
+ }
+ if (recordSummed) {
+ return recordDuration;
+ } else {
+ return summedChildrenDuration;
+ }
+}
+
+function runSimpleBenchmark(config) {
+ var url = config.url;
+ var buttonSelectors = config.buttons;
+ // TODO: Don't use a fixed number of warmup / measure iterations,
+ // but make this dependent on the variance of the test results!
+ var warmupCount = browser.params.warmupCount;
+ var measureCount = browser.params.measureCount;
+ var name = config.name;
+
+ browser.get(url);
+ // TODO(tbosch): replace this with a proper protractor/ng2.0 integration
+ // and remove this function as well as all method calls.
+ browser.sleep(browser.params.sleepInterval)
+
+ var btns = buttonSelectors.map(function(selector) {
+ return $(selector);
+ });
+
+ multiClick(btns, warmupCount);
+ gc();
+ // empty perflogs queue
+ perfLogs();
+
+ multiClick(btns, measureCount);
+ gc();
+ return perfLogs().then(function(logs) {
+ var stats = sumTimelineStats(logs['Timeline.eventRecorded']);
+ printObjectAsMarkdown(name, stats);
+ return stats;
+ });
+}
+
+function gc() {
+ // TODO(tbosch): this only works on chrome.
+ // For iOS Safari we need an extension to appium...
+ browser.executeScript('window.gc()');
+}
+
+function multiClick(buttons, count) {
+ var actions = browser.actions();
+ for (var i=0; i webdriver.logging.Level.WARNING.value;
+ });
+ expect(filteredLog.length).toEqual(0);
+ if (filteredLog.length) {
+ console.log('browser console errors: ' + require('util').inspect(filteredLog));
+ }
+ });
+}
+
+function printObjectAsMarkdown(name, obj) {
+ var props = [['name']];
+ var vals = [name];
+ flattenObj(obj, [], props, vals);
+ // log header
+ var separators = [];
+ var header = props.map(function(propPath) {
+ separators.push('----');
+ return propPath.join('.');
+ }).join(' | ');
+ console.log('\n'+header);
+ console.log(separators.join(' | '));
+ console.log(vals.join(' | '));
+ console.log('\n');
+
+ function flattenObj(obj, propPathPrefix, targetProps, targetVals) {
+ for (var prop in obj) {
+ var val = obj[prop];
+ var currPropPath = propPathPrefix.concat([prop]);
+ if (val && typeof val === 'object') {
+ flattenObj(val, currPropPath, targetProps, targetVals);
+ } else {
+ targetProps.push(currPropPath);
+ var valStr = val;
+ if (typeof val === 'number') {
+ valStr = val.toFixed(2);
+ }
+ targetVals.push(valStr);
+ }
+ }
+ }
+}
\ No newline at end of file