Skip to content

Commit 6100273

Browse files
tboschvicb
authored andcommitted
refactor(benchmarks): make tree benchmark work again
1 parent 5ff14de commit 6100273

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+620
-403
lines changed

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular2",
33
"dependencies": {
4-
"polymer": "Polymer/polymer"
4+
"polymer": "Polymer/polymer#^1.6.0"
55
}
66
}

build.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@ ln -s ../../../../node_modules/rxjs .
3131
ln -s ../../../../node_modules/angular/angular.js .
3232
cd -
3333

34+
echo "====== Copying files needed for benchmarks ====="
35+
cp -r ./modules/benchmarks ./dist/all/
36+
cp -r ./modules/benchmarks/favicon.ico ./dist/
37+
mkdir ./dist/all/benchmarks/vendor
38+
cd ./dist/all/benchmarks/vendor
39+
ln -s ../../../../node_modules/core-js/client/core.js .
40+
ln -s ../../../../node_modules/zone.js/dist/zone.js .
41+
ln -s ../../../../node_modules/zone.js/dist/long-stack-trace-zone.js .
42+
ln -s ../../../../node_modules/systemjs/dist/system.src.js .
43+
ln -s ../../../../node_modules/base64-js/lib/b64.js .
44+
ln -s ../../../../node_modules/reflect-metadata/Reflect.js .
45+
ln -s ../../../../node_modules/rxjs .
46+
ln -s ../../../../node_modules/angular/angular.js .
47+
ln -s ../../../../bower_components/polymer .
48+
cd -
3449

3550
TSCONFIG=./modules/tsconfig.json
3651
echo "====== (all)COMPILING: \$(npm bin)/tsc -p ${TSCONFIG} ====="

gulpfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const os = require('os');
1212

1313
const srcsToFmt =
1414
['tools/**/*.ts', 'modules/@angular/**/*.ts', '!tools/public_api_guard/**/*.d.ts',
15-
'modules/benchpress/**/*.ts', 'modules/playground/**/*.ts'];
15+
'modules/benchpress/**/*.ts', 'modules/playground/**/*.ts', 'modules/benchmarks/**/*.ts'];
1616

1717
gulp.task('format:enforce', () => {
1818
const format = require('gulp-clang-format');

modules/benchmarks/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# How to run the benchmarks locally
2+
3+
## Run in the browser
4+
$ build.sh
5+
$ cp -r ./modules/benchmarks ./dist/all/
6+
$ ./node_modules/.bin/tsc -p modules --emitDecoratorMetadata -w
7+
$ gulp serve
8+
$ open http://localhost:8000/all/benchmarks/src/tree/ng2/index.html?bundles=false
9+
10+
## Run e2e tests
11+
$ export NODE_PATH=$(pwd)/dist/all:$(pwd)/dist/tools
12+
$ ./node_modules/.bin/protractor protractor-js-new-world.conf.js --specs=dist/all/benchmarks/e2e_test/tree_perf.js
Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,37 @@
1-
import {verifyNoBrowserErrors} from '@angular/testing/src/e2e_util';
2-
import {runClickBenchmark} from '@angular/testing/src/perf_util';
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
38

4-
describe('ng2 tree benchmark', function() {
9+
import {verifyNoBrowserErrors} from 'e2e_util/e2e_util';
510

6-
var URL = 'benchmarks/src/tree/tree_benchmark.html';
11+
const useBundles = false;
712

8-
afterEach(verifyNoBrowserErrors);
13+
describe('tree benchmark', function() {
914

10-
it('should log the ng stats', function(done) {
11-
runClickBenchmark({
12-
url: URL,
13-
buttons: ['#ng2DestroyDom', '#ng2CreateDom'],
14-
id: 'ng2.tree.create.plain',
15-
params: [{name: 'depth', value: 9, scale: 'log2'}]
16-
}).then(done, done.fail);
17-
});
15+
afterEach(verifyNoBrowserErrors);
1816

19-
it('should log the ng stats (update)', function(done) {
20-
runClickBenchmark({
21-
url: URL,
22-
buttons: ['#ng2CreateDom'],
23-
id: 'ng2.tree.update',
24-
params: [{name: 'depth', value: 9, scale: 'log2'}]
25-
}).then(done, done.fail);
17+
it('should work for the baseline', function() {
18+
browser.ignoreSynchronization = true;
19+
browser.get(`all/benchmarks/src/tree/baseline/index.html?bundles=${useBundles}`);
20+
$('#createDom').click();
21+
expect($('baseline').getText()).toContain('0');
2622
});
2723

28-
it('should log the baseline stats', function(done) {
29-
runClickBenchmark({
30-
url: URL,
31-
buttons: ['#baselineDestroyDom', '#baselineCreateDom'],
32-
id: 'baseline.tree.create',
33-
params: [{name: 'depth', value: 9, scale: 'log2'}]
34-
}).then(done, done.fail);
24+
it('should work for ng2', function() {
25+
browser.get(`all/benchmarks/src/tree/ng2/index.html?bundles=${useBundles}`);
26+
$('#createDom').click();
27+
expect($('app').getText()).toContain('0');
3528
});
3629

37-
it('should log the baseline stats (update)', function(done) {
38-
runClickBenchmark({
39-
url: URL,
40-
buttons: ['#baselineCreateDom'],
41-
id: 'baseline.tree.update',
42-
params: [{name: 'depth', value: 9, scale: 'log2'}]
43-
}).then(done, done.fail);
30+
it('should work for polymer', function() {
31+
browser.ignoreSynchronization = true;
32+
browser.get(`all/benchmarks/src/tree/polymer/index.html?bundles=${useBundles}`);
33+
$('#createDom').click();
34+
expect($('#app').getText()).toContain('0');
4435
});
4536

4637
});

modules/benchmarks/favicon.ico

5.3 KB
Binary file not shown.

modules/benchmarks/src/bootstrap.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
10+
(function(global: any /** TODO #9100 */) {
11+
12+
writeScriptTag('/all/benchmarks/vendor/core.js');
13+
writeScriptTag('/all/benchmarks/vendor/zone.js');
14+
writeScriptTag('/all/benchmarks/vendor/long-stack-trace-zone.js');
15+
writeScriptTag('/all/benchmarks/vendor/system.src.js');
16+
writeScriptTag('/all/benchmarks/vendor/Reflect.js', 'benchmarksBootstrap()');
17+
18+
(<any>global).benchmarksBootstrap = benchmarksBootstrap;
19+
20+
function benchmarksBootstrap() {
21+
urlParamsToForm();
22+
// check query param
23+
var useBundles = location.search.indexOf('bundles=false') == -1;
24+
if (useBundles) {
25+
System.config({
26+
map: {
27+
'index': 'index.js',
28+
'@angular/core': '/packages-dist/core/bundles/core.umd.js',
29+
'@angular/common': '/packages-dist/common/bundles/common.umd.js',
30+
'@angular/forms': '/packages-dist/forms/bundles/forms.umd.js',
31+
'@angular/compiler': '/packages-dist/compiler/bundles/compiler.umd.js',
32+
'@angular/platform-browser':
33+
'/packages-dist/platform-browser/bundles/platform-browser.umd.js',
34+
'@angular/platform-browser-dynamic':
35+
'/packages-dist/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
36+
'@angular/http': '/packages-dist/http/bundles/http.umd.js',
37+
'@angular/upgrade': '/packages-dist/upgrade/bundles/upgrade.umd.js',
38+
'@angular/router': '/packages-dist/router/bundles/router.umd.js',
39+
'@angular/core/src/facade': '/all/@angular/core/src/facade',
40+
'rxjs': '/all/benchmarks/vendor/rxjs'
41+
},
42+
packages: {
43+
'app': {defaultExtension: 'js'},
44+
'../app': {defaultExtension: 'js'},
45+
'@angular/core/src/facade': {defaultExtension: 'js'},
46+
'rxjs': {defaultExtension: 'js'}
47+
}
48+
});
49+
} else {
50+
console.warn(
51+
'Not using the Angular bundles. Don\'t use this configuration for e2e/performance tests!');
52+
53+
System.config({
54+
map: {
55+
'index': 'index.js',
56+
'@angular': '/all/@angular',
57+
'rxjs': '/all/benchmarks/vendor/rxjs'
58+
},
59+
packages: {
60+
'app': {defaultExtension: 'js'},
61+
'../app': {defaultExtension: 'js'},
62+
'@angular/core': {main: 'index.js', defaultExtension: 'js'},
63+
'@angular/compiler': {main: 'index.js', defaultExtension: 'js'},
64+
'@angular/router': {main: 'index.js', defaultExtension: 'js'},
65+
'@angular/common': {main: 'index.js', defaultExtension: 'js'},
66+
'@angular/forms': {main: 'index.js', defaultExtension: 'js'},
67+
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
68+
'@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'},
69+
'@angular/upgrade': {main: 'index.js', defaultExtension: 'js'},
70+
'rxjs': {defaultExtension: 'js'}
71+
}
72+
});
73+
}
74+
75+
76+
// BOOTSTRAP the app!
77+
System.import('index').then(function(m: any /** TODO #9100 */) {
78+
m.main();
79+
}, console.error.bind(console));
80+
}
81+
82+
83+
function writeScriptTag(scriptUrl: any /** TODO #9100 */, onload?: any /** TODO #9100 */) {
84+
document.write(`<script src="${scriptUrl}" onload="${onload}"></script>`);
85+
}
86+
87+
// helper script that will read out the url parameters
88+
// and store them in appropriate form fields on the page
89+
function urlParamsToForm() {
90+
var regex = /(\w+)=(\w+)/g;
91+
var search = decodeURIComponent(location.search);
92+
var match: any[];
93+
while (match = regex.exec(search)) {
94+
var name = match[1];
95+
var value = match[2];
96+
var els = document.querySelectorAll('input[name="'+name+'"]');
97+
var el: any;
98+
for (var i=0; i<els.length; i++) {
99+
el = els[i];
100+
if (el.type === 'radio' || el.type === 'checkbox') {
101+
el.checked = el.value === value;
102+
} else {
103+
el.value = value;
104+
}
105+
}
106+
}
107+
}
108+
}(window));

modules/benchmarks/src/largetable/largetable_benchmark.ts renamed to modules/benchmarks/src/old/largetable/largetable_benchmark.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function _createBindings() {
2626
return [
2727
{provide: BENCHMARK_TYPE, useValue: getStringParameter('benchmarkType')},
2828
{provide: LARGETABLE_ROWS, useValue: getIntParameter('rows')},
29-
{provide: LARGETABLE_COLS, {useValue: getIntParameter('columns')},
29+
{provide: LARGETABLE_COLS, useValue: getIntParameter('columns')},
3030
];
3131
}
3232

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import {
2+
getIntParameter,
3+
windowProfile,
4+
windowProfileEnd
5+
} from '@angular/platform-browser/testing/benchmark_util';
6+
7+
export class TreeNode {
8+
constructor(public value: string, public left: TreeNode, public right: TreeNode) {
9+
}
10+
}
11+
12+
let treeCreateCount: number;
13+
let maxDepth: number;
14+
let numberData: string[];
15+
let charData: string[];
16+
17+
init();
18+
19+
function init() {
20+
maxDepth = getIntParameter('depth');
21+
treeCreateCount = 0;
22+
numberData = [];
23+
charData = [];
24+
for (let i = 0; i<maxDepth; i++) {
25+
numberData.push(i.toString());
26+
charData.push(String.fromCharCode('A'.charCodeAt(0) + i));
27+
}
28+
}
29+
30+
function _buildTree(values: string[], curDepth: number = 0): TreeNode {
31+
if (maxDepth === curDepth) return new TreeNode('', null, null);
32+
return new TreeNode(values[curDepth], _buildTree(values, curDepth + 1),
33+
_buildTree(values, curDepth + 1));
34+
}
35+
36+
export function emptyTree(): TreeNode {
37+
return new TreeNode('', null, null);
38+
}
39+
40+
export function buildTree(): TreeNode {
41+
treeCreateCount++;
42+
return _buildTree(treeCreateCount % 2 ? numberData : charData);
43+
}
44+
45+
export function profile(create: () => void, destroy: () => void, name: string) {
46+
return function() {
47+
windowProfile(name + ' w GC');
48+
var duration = 0;
49+
var count = 0;
50+
while (count++ < 150) {
51+
(<any>window)['gc']();
52+
var start = window.performance.now();
53+
create();
54+
duration += window.performance.now() - start;
55+
destroy();
56+
}
57+
windowProfileEnd(name + ' w GC');
58+
window.console.log(`Iterations: ${count}; time: ${duration / count} ms / iteration`);
59+
60+
windowProfile(name + ' w/o GC');
61+
duration = 0;
62+
count = 0;
63+
while (count++ < 150) {
64+
var start = window.performance.now();
65+
create();
66+
duration += window.performance.now() - start;
67+
destroy();
68+
}
69+
windowProfileEnd(name + ' w/o GC');
70+
window.console.log(`Iterations: ${count}; time: ${duration / count} ms / iteration`);
71+
};
72+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
2+
import {TreeNode} from '../../app/util';
3+
4+
// http://jsperf.com/nextsibling-vs-childnodes
5+
6+
const BASELINE_TREE_TEMPLATE =document.createElement('template');
7+
BASELINE_TREE_TEMPLATE.innerHTML = '<span>_<template class="ng-provider"></template><template class="ng-provider"></template></span>';
8+
const BASELINE_IF_TEMPLATE =document.createElement('template');
9+
BASELINE_IF_TEMPLATE.innerHTML = '<span template="if"><tree></tree></span>';
10+
11+
export class BaseLineTreeComponent {
12+
value: BaseLineInterpolation;
13+
left: BaseLineIf;
14+
right: BaseLineIf;
15+
constructor(public element: HTMLElement) {
16+
var clone = getDOM().clone(BASELINE_TREE_TEMPLATE.content.firstChild);
17+
getDOM().appendChild(element, clone);
18+
19+
var child = clone.firstChild;
20+
this.value = new BaseLineInterpolation(child);
21+
child = getDOM().nextSibling(child);
22+
this.left = new BaseLineIf(child);
23+
child = getDOM().nextSibling(child);
24+
this.right = new BaseLineIf(child);
25+
}
26+
update(value: TreeNode) {
27+
this.value.update(value.value);
28+
this.left.update(value.left);
29+
this.right.update(value.right);
30+
}
31+
}
32+
33+
export class BaseLineInterpolation {
34+
value: string;
35+
constructor(public textNode: Node) {
36+
this.value = null;
37+
}
38+
update(value: string) {
39+
if (this.value !== value) {
40+
this.value = value;
41+
getDOM().setText(this.textNode, value + ' ');
42+
}
43+
}
44+
}
45+
46+
export class BaseLineIf {
47+
condition: boolean;
48+
component: BaseLineTreeComponent;
49+
constructor(public anchor: Node) {
50+
this.condition = false;
51+
this.component = null;
52+
}
53+
update(value: TreeNode) {
54+
var newCondition = !!value;
55+
if (this.condition !== newCondition) {
56+
this.condition = newCondition;
57+
if (this.component) {
58+
getDOM().remove(this.component.element);
59+
this.component = null;
60+
}
61+
if (this.condition) {
62+
var element = getDOM().firstChild((<any>getDOM().clone(BASELINE_IF_TEMPLATE)).content);
63+
this.anchor.parentNode.insertBefore(element, getDOM().nextSibling(this.anchor));
64+
this.component = new BaseLineTreeComponent(<HTMLElement>getDOM().firstChild(element));
65+
}
66+
}
67+
if (this.component) {
68+
this.component.update(value);
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)