diff --git a/modules/benchmarks/src/benchpress.dart b/modules/benchmarks/src/benchpress.dart
new file mode 100644
index 0000000000..81542709bd
--- /dev/null
+++ b/modules/benchmarks/src/benchpress.dart
@@ -0,0 +1,63 @@
+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/benchmarks/src/benchpress.es6 b/modules/benchmarks/src/benchpress.es6
new file mode 100644
index 0000000000..d5e5d5e0df
--- /dev/null
+++ b/modules/benchmarks/src/benchpress.es6
@@ -0,0 +1,55 @@
+// 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/benchmarks/src/compiler/benchmark.dart b/modules/benchmarks/src/compiler/benchmark.dart
index d78e810612..c8aa1fc047 100644
--- a/modules/benchmarks/src/compiler/benchmark.dart
+++ b/modules/benchmarks/src/compiler/benchmark.dart
@@ -2,35 +2,8 @@ library compiler_benchmark;
import './selector_benchmark.dart' as sbm;
import './compiler_benchmark.dart' as cbm;
-import 'dart:js' as js;
main () {
- sbm.setup();
- cbm.setup();
-
- js.context['benchmarkSteps'].add(new js.JsObject.jsify({
- "name": "CssSelector.parse * 1000",
- "fn": new js.JsFunction.withThis((_) => sbm.runParse())
- }));
- js.context['benchmarkSteps'].add(new js.JsObject.jsify({
- "name": "SelectorMatcher.addSelectable * 1000",
- "fn": new js.JsFunction.withThis((_) => sbm.runAdd())
- }));
- js.context['benchmarkSteps'].add(new js.JsObject.jsify({
- "name": "SelectorMatcher.match * 1000",
- "fn": new js.JsFunction.withThis((_) => sbm.runMatch())
- }));
-
- js.context['benchmarkSteps'].add(new js.JsObject.jsify({
- "name": "Compiler.compile empty template",
- "fn": new js.JsFunction.withThis((_) => cbm.compileEmptyTemplate())
- }));
- js.context['benchmarkSteps'].add(new js.JsObject.jsify({
- "name": "Compiler.compile 25 element no bindings",
- "fn": new js.JsFunction.withThis((_) => cbm.compile25ElementsNoBindings())
- }));
- js.context['benchmarkSteps'].add(new js.JsObject.jsify({
- "name": "Compiler.compile 25 element with bindings",
- "fn": new js.JsFunction.withThis((_) => cbm.compile25ElementsWithBindings())
- }));
+ sbm.main();
+ cbm.main();
}
\ No newline at end of file
diff --git a/modules/benchmarks/src/compiler/benchmark.es5 b/modules/benchmarks/src/compiler/benchmark.es5
index 4be167af17..760118bd84 100644
--- a/modules/benchmarks/src/compiler/benchmark.es5
+++ b/modules/benchmarks/src/compiler/benchmark.es5
@@ -1,35 +1,9 @@
-System.import('benchmarks/compiler/selector_benchmark').then(function (bm) {
- bm.setup();
-
- window.benchmarkSteps.push({name: 'CssSelector.parse * 1000', fn: bm.runParse});
-}, console.log.bind(console));
-
-System.import('benchmarks/compiler/selector_benchmark').then(function (bm) {
- bm.setup();
-
- window.benchmarkSteps.push({name: 'SelectorMatcher.addSelectable * 1000', fn: bm.runAdd});
-}, console.log.bind(console));
-
-System.import('benchmarks/compiler/selector_benchmark').then(function (bm) {
- bm.setup();
-
- window.benchmarkSteps.push({name: 'SelectorMatcher.match * 1000', fn: bm.runMatch});
-}, console.log.bind(console));
-
-System.import('benchmarks/compiler/compiler_benchmark').then(function (bm) {
- bm.setup();
-
- window.benchmarkSteps.push({name: 'Compiler.compile empty template', fn: bm.compileEmptyTemplate});
-}, console.log.bind(console));
-
-System.import('benchmarks/compiler/compiler_benchmark').then(function (bm) {
- bm.setup();
-
- window.benchmarkSteps.push({name: 'Compiler.compile 25 element no bindings', fn: bm.compile25ElementsNoBindings});
-}, console.log.bind(console));
-
-System.import('benchmarks/compiler/compiler_benchmark').then(function (bm) {
- bm.setup();
-
- window.benchmarkSteps.push({name: 'Compiler.compile 25 element with bindings', fn: bm.compile25ElementsWithBindings});
+Promise.all([
+ System.import('benchmarks/compiler/selector_benchmark'),
+ System.import('benchmarks/compiler/compiler_benchmark'),
+ System.import('benchmarks/compiler/compiler_benchmark_ng13')
+]).then(function (benchmarks) {
+ benchmarks.forEach(function(bm) {
+ bm.main();
+ });
}, console.log.bind(console));
diff --git a/modules/benchmarks/src/compiler/bp.conf.es5 b/modules/benchmarks/src/compiler/bp.conf.es5
index b9ff8a4015..7991da976d 100644
--- a/modules/benchmarks/src/compiler/bp.conf.es5
+++ b/modules/benchmarks/src/compiler/bp.conf.es5
@@ -4,7 +4,8 @@ module.exports = function(config) {
{src: '/js/traceur-runtime.js'},
{src: '/js/es6-module-loader-sans-promises.src.js'},
{src: '/js/extension-register.js'},
- {src: 'register_system.js'},
+ {src: 'paths.js'},
+ {src: 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js'},
{src: 'benchmark.js'}
]
});
diff --git a/modules/benchmarks/src/compiler/compiler_benchmark.js b/modules/benchmarks/src/compiler/compiler_benchmark.js
index 5b9ed81864..5f6a82e2bb 100644
--- a/modules/benchmarks/src/compiler/compiler_benchmark.js
+++ b/modules/benchmarks/src/compiler/compiler_benchmark.js
@@ -1,4 +1,9 @@
-import {DOM} from 'facade/dom';
+import {benchmark, benchmarkStep} from '../benchpress';
+
+import {DOM, document} from 'facade/dom';
+import {isBlank} from 'facade/lang';
+import {MapWrapper} from 'facade/collection';
+import {AnnotatedType} from 'core/compiler/annotated_type';
import {Parser} from 'change_detection/parser/parser';
import {ClosureMap} from 'change_detection/parser/closure_map';
@@ -11,39 +16,65 @@ import {Component} from 'core/annotations/component';
import {Decorator} from 'core/annotations/decorator';
import {TemplateConfig} from 'core/annotations/template_config';
+var COUNT = 30;
+
var compiler;
var annotatedComponent;
-var annotatedComponentNoDirectives;
-var emptyTemplate;
-var templateWith25ElementsNoBindings;
-var templateWith25ElementsAndBindings;
-
-export function setup() {
+function setup() {
var closureMap = new ClosureMap();
- var reflector = new Reflector();
+ var reflector = new CachingReflector();
compiler = new Compiler(null, reflector, new Parser(new Lexer(), closureMap), closureMap);
- annotatedComponent = reflector.annotatedType(SomeComponent);
- annotatedComponentNoDirectives = reflector.annotatedType(ComponentWithNoDirectives);
-
- emptyTemplate = createTemplate('');
- templateWith25ElementsNoBindings = buildTemplateWith25ElementsNoBindings();
- templateWith25ElementsAndBindings = buildTemplateWith25ElementsAndBindings();
+ annotatedComponent = reflector.annotatedType(BenchmarkComponent);
}
-export function compileEmptyTemplate() {
- var template = emptyTemplate;
- return compiler.compileWithCache(null, annotatedComponent, template);
+export function main() {
+ setup();
+
+ benchmark(`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 = DOM.clone(template);
+ compiler.compileWithCache(null, annotatedComponent, cloned);
+ });
+ });
+
+ benchmark(`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 = DOM.clone(template);
+ compiler.compileWithCache(null, annotatedComponent, cloned);
+ });
+ });
}
-export function compile25ElementsWithBindings() {
- var template = templateWith25ElementsAndBindings;
- return compiler.compileWithCache(null, annotatedComponent, template);
+function loadTemplate(templateId, repeatCount) {
+ var template = DOM.querySelectorAll(document, `#${templateId}`)[0];
+ var content = DOM.getInnerHTML(template);
+ var result = '';
+ for (var i=0; i
-//
-function buildTemplateWith25ElementsNoBindings() {
- var result = '';
- for (var i=0; i<5; i++) {
- for (var j=0; j<5; j++) {
- result += '';
- }
- for (var j=0; j<5; j++) {
- result += '
';
- }
- }
- return createTemplate(result);
-}
-
-// creates 25 nested divs , each looking like this:
-//
-// {{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
-//
-function buildTemplateWith25ElementsAndBindings() {
- var result = '';
- for (var i=0; i<5; i++) {
- for (var j=0; j<5; j++) {
- result += '';
- for (var k=0; k<5; k++) {
- result += `{{inter${k}}}`;
- }
- }
- for (var j=0; j<5; j++) {
- result += '
';
- }
- }
- return createTemplate(result);
-}
-
-
-
-function createTemplate(html) {
- return DOM.createTemplate(html);
-}
diff --git a/modules/benchmarks/src/compiler/compiler_benchmark_ng13.es6 b/modules/benchmarks/src/compiler/compiler_benchmark_ng13.es6
new file mode 100644
index 0000000000..e4b2a4db19
--- /dev/null
+++ b/modules/benchmarks/src/compiler/compiler_benchmark_ng13.es6
@@ -0,0 +1,102 @@
+import {benchmark, benchmarkStep} from '../benchpress';
+
+var COUNT = 30;
+var $compile;
+
+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);
+ });
+ });
+
+ var ngEl = document.createElement('div');
+ angular.bootstrap(ngEl, ['app']);
+}
+
+function loadTemplate(templateId, repeatCount) {
+ var template = document.querySelectorAll(`#${templateId}`)[0];
+ var content = template.innerHTML;
+ var result = '';
+ for (var i=0; i elements...
+ var div = document.createElement('div');
+ div.innerHTML = result;
+ return div;
+}
+
+angular.module('app', [])
+.directive('dir0', function($parse) {
+ return {
+ compile: function($element, $attrs) {
+ var expr = $parse($attrs.attr0);
+ return function($scope) {
+ $scope.$watch(expr, angular.noop);
+ }
+ }
+ };
+})
+.directive('dir1', function($parse) {
+ return {
+ compile: function($element, $attrs) {
+ var expr = $parse($attrs.attr1);
+ return function($scope) {
+ $scope.$watch(expr, angular.noop);
+ }
+ }
+ };
+})
+.directive('dir2', function($parse) {
+ return {
+ compile: function($element, $attrs) {
+ var expr = $parse($attrs.attr2);
+ return function($scope) {
+ $scope.$watch(expr, angular.noop);
+ }
+ }
+ };
+})
+.directive('dir3', function($parse) {
+ return {
+ compile: function($element, $attrs) {
+ var expr = $parse($attrs.attr3);
+ return function($scope) {
+ $scope.$watch(expr, angular.noop);
+ }
+ }
+ };
+})
+.directive('dir4', function($parse) {
+ return {
+ compile: function($element, $attrs) {
+ var expr = $parse($attrs.attr4);
+ return function($scope) {
+ $scope.$watch(expr, angular.noop);
+ }
+ }
+ };
+})
+.run(function(_$compile_) {
+ $compile = _$compile_;
+});
+
diff --git a/modules/benchmarks/src/compiler/main.html b/modules/benchmarks/src/compiler/main.html
index e69de29bb2..d16b04e8fa 100644
--- a/modules/benchmarks/src/compiler/main.html
+++ b/modules/benchmarks/src/compiler/main.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+ {{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
+
+ {{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
+
+ {{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
+
+ {{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
+
+ {{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
+
+
+
+
+
+
diff --git a/modules/benchmarks/src/compiler/register_system.es5 b/modules/benchmarks/src/compiler/paths.es5
similarity index 100%
rename from modules/benchmarks/src/compiler/register_system.es5
rename to modules/benchmarks/src/compiler/paths.es5
diff --git a/modules/benchmarks/src/compiler/selector_benchmark.js b/modules/benchmarks/src/compiler/selector_benchmark.js
index 34d558ee07..7873c43686 100644
--- a/modules/benchmarks/src/compiler/selector_benchmark.js
+++ b/modules/benchmarks/src/compiler/selector_benchmark.js
@@ -1,3 +1,5 @@
+import {benchmark, benchmarkStep} from '../benchpress';
+
import {SelectorMatcher} from "core/compiler/selector";
import {CssSelector} from "core/compiler/selector";
import {StringWrapper, Math} from 'facade/lang';
@@ -9,46 +11,55 @@ var fixedSelectors = [];
var COUNT = 1000;
-export function setup() {
- for (var i=0; i {
+ matchCount += selected;
+ });
+ }
+ return matchCount;
+ });
+ });
+}
+
+function setup(count) {
+ for (var i=0; i {
- count += selected;
- });
- }
- return count;
-}
-
function randomSelector() {
var res = randomStr(5);
for (var i=0; i<3; i++) {
diff --git a/modules/change_detection/src/parser/closure_map.dart b/modules/change_detection/src/parser/closure_map.dart
index 615ee34b27..5f4ae78d19 100644
--- a/modules/change_detection/src/parser/closure_map.dart
+++ b/modules/change_detection/src/parser/closure_map.dart
@@ -1,3 +1,5 @@
+library change_detection.parser.closure_map;
+
import 'dart:mirrors';
typedef SetterFn(Object obj, value);
diff --git a/modules/facade/src/dom.dart b/modules/facade/src/dom.dart
index 4a08921ec8..4685340521 100644
--- a/modules/facade/src/dom.dart
+++ b/modules/facade/src/dom.dart
@@ -3,7 +3,7 @@ library angular.core.facade.dom;
import 'dart:html';
import 'dart:js' show JsObject;
-export 'dart:html' show DocumentFragment, Node, Element, TemplateElement, Text;
+export 'dart:html' show DocumentFragment, Node, Element, TemplateElement, Text, document, location;
// TODO(tbosch): Is there a builtin one? Why is Dart
// removing unknown elements by default?
diff --git a/modules/facade/src/dom.es6 b/modules/facade/src/dom.es6
index c5c722f983..e3be55146c 100644
--- a/modules/facade/src/dom.es6
+++ b/modules/facade/src/dom.es6
@@ -4,6 +4,9 @@ export var NodeList = window.NodeList;
export var Text = window.Text;
export var Element = window.HTMLElement;
export var TemplateElement = window.HTMLTemplateElement;
+export var document = window.document;
+export var location = window.location;
+
import {List, MapWrapper} from 'facade/collection';
export class DOM {