diff --git a/modules/benchmarks/e2e_test/tree_perf.ts b/modules/benchmarks/e2e_test/tree_perf.ts
index 0c5c60dc88..61f3e4d97f 100644
--- a/modules/benchmarks/e2e_test/tree_perf.ts
+++ b/modules/benchmarks/e2e_test/tree_perf.ts
@@ -19,6 +19,13 @@ describe('tree benchmark perf', () => {
}).then(done, done.fail);
});
+ it('should run for ng2 static', (done) => {
+ runTreeBenchmark({
+ id: 'deepTree.ng2.static',
+ url: 'all/benchmarks/src/tree/ng2_static/index.html',
+ }).then(done, done.fail);
+ });
+
it('should run for the baseline', (done) => {
runTreeBenchmark({
id: 'deepTree.baseline',
diff --git a/modules/benchmarks/e2e_test/tree_spec.ts b/modules/benchmarks/e2e_test/tree_spec.ts
index e5fcb8eb45..d3fdd36062 100644
--- a/modules/benchmarks/e2e_test/tree_spec.ts
+++ b/modules/benchmarks/e2e_test/tree_spec.ts
@@ -18,6 +18,12 @@ describe('tree benchmark spec', () => {
});
});
+ it('should work for ng2 static', () => {
+ testTreeBenchmark({
+ url: 'all/benchmarks/src/tree/ng2_static/index.html',
+ });
+ });
+
it('should work for the baseline', () => {
testTreeBenchmark({
url: 'all/benchmarks/src/tree/baseline/index.html',
diff --git a/modules/benchmarks/src/old/static_tree/tree_benchmark.html b/modules/benchmarks/src/old/static_tree/tree_benchmark.html
deleted file mode 100644
index 2c8e2cbaf8..0000000000
--- a/modules/benchmarks/src/old/static_tree/tree_benchmark.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-Params
-
-
-Angular2 static tree benchmark (depth 10)
-
-
-
-
-
-
-
-Baseline static tree benchmark (depth 10)
-
-
-
-
-
-
-
-
-
-
-
-
-
-$SCRIPTS$
-
-
diff --git a/modules/benchmarks/src/old/static_tree/tree_benchmark.ts b/modules/benchmarks/src/old/static_tree/tree_benchmark.ts
deleted file mode 100644
index 39768072a1..0000000000
--- a/modules/benchmarks/src/old/static_tree/tree_benchmark.ts
+++ /dev/null
@@ -1,325 +0,0 @@
-import {NgIf} from '@angular/common';
-import {Component, NgModule} from '@angular/core';
-import {ApplicationRef} from '@angular/core/src/application_ref';
-import {reflector} from '@angular/core/src/reflection/reflection';
-import {ReflectionCapabilities} from '@angular/core/src/reflection/reflection_capabilities';
-import {document, gc, window} from '@angular/facade/src/browser';
-import {BrowserModule} from '@angular/platform-browser';
-import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
-import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter';
-import {DOM} from '@angular/platform-browser/src/dom/dom_adapter';
-import {bindAction, getIntParameter, getStringParameter, windowProfile, windowProfileEnd} from '@angular/testing/src/benchmark_util';
-
-function createBindings(): any[] {
- return [];
-}
-
-function setupReflector() {
- reflector.reflectionCapabilities = new ReflectionCapabilities();
-}
-
-const MAX_DEPTH = 10;
-
-export function main() {
- BrowserDomAdapter.makeCurrent();
-
- setupReflector();
-
- var app;
- var appRef;
- var baselineRootTreeComponent;
- var count = 0;
-
- function profile(create, destroy, name) {
- return function() {
- windowProfile(name + ' w GC');
- var duration = 0;
- var count = 0;
- while (count++ < 150) {
- gc();
- var start = window.performance.now();
- create();
- duration += window.performance.now() - start;
- destroy();
- }
- windowProfileEnd(name + ' w GC');
- window.console.log(`Iterations: ${count}; time: ${duration / count} ms / iteration`);
-
- windowProfile(name + ' w/o GC');
- duration = 0;
- count = 0;
- while (count++ < 150) {
- var start = window.performance.now();
- create();
- duration += window.performance.now() - start;
- destroy();
- }
- windowProfileEnd(name + ' w/o GC');
- window.console.log(`Iterations: ${count}; time: ${duration / count} ms / iteration`);
- };
- }
-
- function noop() {}
-
- function createData(): TreeNode {
- 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', '-'];
- return buildTree(MAX_DEPTH, values, 0);
- }
-
- function ng2DestroyDom() {
- app.initData = null;
- appRef.tick();
- }
-
- function ng2CreateDom() {
- app.initData = createData();
- appRef.tick();
- }
-
- @NgModule({
- imports: [BrowserModule],
- bootstrap: [AppComponentWithStaticTree],
- providers: createBindings()
- })
- class AppModule {
- }
-
- function initNg2() {
- platformBrowserDynamic().bootstrapModule(AppModule).then((ref) => {
- var injector = ref.injector;
- appRef = injector.get(ApplicationRef);
-
- app = ref.instance;
- bindAction('#ng2DestroyDom', ng2DestroyDom);
- bindAction('#ng2CreateDom', ng2CreateDom);
- bindAction('#ng2UpdateDomProfile', profile(ng2CreateDom, noop, 'ng2-update'));
- bindAction('#ng2CreateDomProfile', profile(ng2CreateDom, ng2DestroyDom, 'ng2-create'));
- });
- }
-
- function baselineDestroyDom() { baselineRootTreeComponent.update(null); }
-
- function baselineCreateDom() { baselineRootTreeComponent.update(createData()); }
-
- function initBaseline() {
- var tree = DOM.createElement('tree');
- DOM.appendChild(DOM.querySelector(document, 'baseline'), tree);
- baselineRootTreeComponent = new BaselineAppComponent(tree, MAX_DEPTH);
-
- bindAction('#baselineDestroyDom', baselineDestroyDom);
- bindAction('#baselineCreateDom', baselineCreateDom);
-
- bindAction('#baselineUpdateDomProfile', profile(baselineCreateDom, noop, 'baseline-update'));
- bindAction(
- '#baselineCreateDomProfile',
- profile(baselineCreateDom, baselineDestroyDom, 'baseline-create'));
- }
-
- initNg2();
- initBaseline();
-}
-
-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));
-}
-
-// http://jsperf.com/nextsibling-vs-childnodes
-
-class BaselineAppComponent {
- tree: BaseLineTreeComponent = null;
- constructor(public element, public depth: number) {}
- update(value: TreeNode) {
- if (value === null) {
- this.tree = null;
- DOM.clearNodes(this.element);
- } else {
- if (this.tree === null) {
- this.tree = new BaseLineTreeComponent(this.element, this.depth);
- }
- this.tree.update(value);
- }
- }
-}
-
-var BASELINE_TREE_TEMPLATE = null;
-class BaseLineTreeComponent {
- static getTemplate() {
- if (BASELINE_TREE_TEMPLATE === null) {
- BASELINE_TREE_TEMPLATE = DOM.createTemplate('_');
- }
- return BASELINE_TREE_TEMPLATE;
- }
-
- value: BaseLineInterpolation;
- left: BaseLineTreeComponent;
- right: BaseLineTreeComponent;
- terminal: boolean;
-
- constructor(public element, remainingDepth: number) {
- var clone = DOM.firstChild(DOM.importIntoDoc(BaseLineTreeComponent.getTemplate().content));
- DOM.appendChild(this.element, clone);
- var child = clone.firstChild;
- this.value = new BaseLineInterpolation(child);
- this.terminal = remainingDepth === 0;
- if (!this.terminal) {
- child = DOM.nextSibling(child);
- this.left = new BaseLineTreeComponent(child, remainingDepth - 1);
- child = DOM.nextSibling(child);
- this.right = new BaseLineTreeComponent(child, remainingDepth - 1);
- }
- }
- update(value: TreeNode) {
- this.value.update(value.value);
- if (!this.terminal) {
- this.left.update(value.left);
- this.right.update(value.right);
- }
- }
-}
-
-class BaseLineInterpolation {
- value: string;
- textNode;
- constructor(textNode) {
- this.value = null;
- this.textNode = textNode;
- }
- update(value: string) {
- if (this.value !== value) {
- this.value = value;
- DOM.setText(this.textNode, value + ' ');
- }
- }
-}
-
-class StaticTreeComponentBase {
- _value: TreeNode;
- constructor() { this.data = null; }
- set data(value: TreeNode) {
- // TODO: We need an initial value as otherwise the getter for data.value will fail
- // --> this should be already caught in change detection!
- value = value !== null ? value : new TreeNode('', null, null);
- this._value = value;
- }
- get data() { return this._value; }
-}
-
-@Component(
- {selector: 'tree', inputs: ['data'], directives: [], template: '{{data.value}} '})
-class StaticTreeComponent0 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent0],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent1 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent1],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent2 extends StaticTreeComponentBase {
- data: TreeNode;
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent2],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent3 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent3],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent4 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent4],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent5 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent5],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent6 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent6],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent7 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent7],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent8 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'tree',
- inputs: ['data'],
- directives: [StaticTreeComponent8],
- template:
- ` {{data.value}} `
-})
-class StaticTreeComponent9 extends StaticTreeComponentBase {
-}
-
-@Component({
- selector: 'app',
- directives: [StaticTreeComponent9, NgIf],
- template: ``
-})
-class AppComponentWithStaticTree {
- initData: TreeNode;
-}
diff --git a/modules/benchmarks/src/tree/ng2_static/index.html b/modules/benchmarks/src/tree/ng2_static/index.html
new file mode 100644
index 0000000000..17031dfe68
--- /dev/null
+++ b/modules/benchmarks/src/tree/ng2_static/index.html
@@ -0,0 +1,26 @@
+
+
+
+ Params
+
+
+ Angular2 tree benchmark
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/benchmarks/src/tree/ng2_static/index.ts b/modules/benchmarks/src/tree/ng2_static/index.ts
new file mode 100644
index 0000000000..2a21d68710
--- /dev/null
+++ b/modules/benchmarks/src/tree/ng2_static/index.ts
@@ -0,0 +1,40 @@
+import {ApplicationRef, NgModule, enableProdMode} from '@angular/core';
+import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
+
+import {bindAction, profile} from '../../util';
+import {TreeNode, buildTree, emptyTree} from '../util';
+
+import {AppModule, RootTreeComponent} from './tree';
+
+export function main() {
+ var tree: RootTreeComponent;
+ var appRef: ApplicationRef;
+
+ function destroyDom() {
+ tree.data = emptyTree;
+ appRef.tick();
+ }
+
+ function createDom() {
+ tree.data = buildTree();
+ appRef.tick();
+ }
+
+ function noop() {}
+
+ function init() {
+ enableProdMode();
+ platformBrowserDynamic().bootstrapModule(AppModule).then((ref) => {
+ const injector = ref.injector;
+ appRef = injector.get(ApplicationRef);
+
+ tree = appRef.components[0].instance;
+ bindAction('#destroyDom', destroyDom);
+ bindAction('#createDom', createDom);
+ bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
+ bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));
+ });
+ }
+
+ init();
+}
diff --git a/modules/benchmarks/src/tree/ng2_static/tree.ts b/modules/benchmarks/src/tree/ng2_static/tree.ts
new file mode 100644
index 0000000000..3a319782e9
--- /dev/null
+++ b/modules/benchmarks/src/tree/ng2_static/tree.ts
@@ -0,0 +1,40 @@
+import {Component, Input, NgModule} from '@angular/core';
+import {BrowserModule} from '@angular/platform-browser';
+
+import {TreeNode, emptyTree, maxDepth} from '../util';
+
+function createTreeComponent(level: number, isLeaf: boolean) {
+ const nextTreeEl = `tree${level+1}`;
+ const template = isLeaf ?
+ ` {{data.value}} ` :
+ ` {{data.value}} <${nextTreeEl} [data]='data.right'>${nextTreeEl}><${nextTreeEl} [data]='data.left'>${nextTreeEl}>`;
+
+ @Component({selector: `tree${level}`, template: template})
+ class TreeComponent {
+ @Input()
+ data: TreeNode;
+ }
+
+ return TreeComponent;
+}
+
+@Component({selector: 'tree', template: ``})
+export class RootTreeComponent {
+ @Input()
+ data: TreeNode = emptyTree;
+}
+
+function createModule(): any {
+ const components: any[] = [RootTreeComponent];
+ for (var i = 0; i <= maxDepth; i++) {
+ components.push(createTreeComponent(i, i === maxDepth));
+ }
+
+ @NgModule({imports: [BrowserModule], bootstrap: [RootTreeComponent], declarations: [components]})
+ class AppModule {
+ }
+
+ return AppModule;
+}
+
+export const AppModule = createModule();
diff --git a/modules/benchmarks/src/tree/util.ts b/modules/benchmarks/src/tree/util.ts
index 37e135b040..6de028fca1 100644
--- a/modules/benchmarks/src/tree/util.ts
+++ b/modules/benchmarks/src/tree/util.ts
@@ -5,7 +5,7 @@ export class TreeNode {
}
let treeCreateCount: number;
-let maxDepth: number;
+export let maxDepth: number;
let numberData: string[];
let charData: string[];