From 6ea5b05e7c47353b3dab0bf16742ff8ad4b80728 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Tue, 30 Aug 2016 14:17:37 -0700 Subject: [PATCH] refactor(benchmarks): make setup nicer - simplify and correct systemjs config - remove deep imports into Ng2 packages to work with bundles - have separate Ng2 and Polymer bootstrap files --- .../{tsconfig-es5.json => tsconfig.json} | 7 +- .../testing/benchmark_util.ts | 61 ------------- modules/@angular/router/src/router.ts | 2 +- modules/benchmarks/e2e_test/tree_perf.ts | 56 ++++++------ modules/benchmarks/e2e_test/tree_spec.ts | 37 ++++---- .../src/{bootstrap.ts => bootstrap_ng2.ts} | 47 ++-------- modules/benchmarks/src/bootstrap_polymer.ts | 26 ++++++ modules/benchmarks/src/index.html | 37 -------- modules/benchmarks/src/tree/app/util.ts | 67 -------------- .../benchmarks/src/tree/baseline/index.html | 4 +- modules/benchmarks/src/tree/baseline/index.ts | 15 ++-- .../src/tree/baseline/{app => }/tree.ts | 10 ++- modules/benchmarks/src/tree/ng2/index.html | 4 +- modules/benchmarks/src/tree/ng2/index.ts | 17 ++-- .../benchmarks/src/tree/ng2/{app => }/tree.ts | 18 +--- .../benchmarks/src/tree/polymer/index.html | 4 +- modules/benchmarks/src/tree/polymer/index.ts | 9 +- .../src/tree/polymer_leaves/index.html | 6 +- .../src/tree/polymer_leaves/index.ts | 7 +- modules/benchmarks/src/tree/util.ts | 36 ++++++++ modules/benchmarks/src/util.ts | 90 +++++++++++++++++++ modules/e2e_util/e2e_util.ts | 3 + protractor-e2e.conf.js | 5 ++ protractor-perf.conf.js | 8 +- scripts/ci-lite/install.sh | 4 +- 25 files changed, 260 insertions(+), 320 deletions(-) rename modules/@angular/benchpress/{tsconfig-es5.json => tsconfig.json} (71%) delete mode 100644 modules/@angular/platform-browser/testing/benchmark_util.ts rename modules/benchmarks/src/{bootstrap.ts => bootstrap_ng2.ts} (68%) create mode 100644 modules/benchmarks/src/bootstrap_polymer.ts delete mode 100644 modules/benchmarks/src/index.html delete mode 100644 modules/benchmarks/src/tree/app/util.ts rename modules/benchmarks/src/tree/baseline/{app => }/tree.ts (83%) rename modules/benchmarks/src/tree/ng2/{app => }/tree.ts (51%) create mode 100644 modules/benchmarks/src/tree/util.ts create mode 100644 modules/benchmarks/src/util.ts diff --git a/modules/@angular/benchpress/tsconfig-es5.json b/modules/@angular/benchpress/tsconfig.json similarity index 71% rename from modules/@angular/benchpress/tsconfig-es5.json rename to modules/@angular/benchpress/tsconfig.json index f21137b9f1..2f27422d91 100644 --- a/modules/@angular/benchpress/tsconfig-es5.json +++ b/modules/@angular/benchpress/tsconfig.json @@ -7,21 +7,20 @@ "sourceMap": true, "baseUrl": ".", "paths": { - "@angular/core": ["../../../dist/packages-dist/core"], - "selenium-webdriver": ["../../../node_modules/@types/selenium-webdriver/index.d.ts"] + "@angular/core": ["../../../dist/packages-dist/core"] }, "experimentalDecorators": true, "rootDir": ".", "sourceRoot": ".", "outDir": "../../../dist/packages-dist/benchpress", - "declaration": true + "declaration": true, + "skipLibCheck": true }, "exclude": ["integrationtest"], "files": [ "index.ts", "../../../node_modules/@types/node/index.d.ts", "../../../node_modules/@types/jasmine/index.d.ts", - "../../../node_modules/@types/protractor/index.d.ts", "../../../node_modules/zone.js/dist/zone.js.d.ts" ] } diff --git a/modules/@angular/platform-browser/testing/benchmark_util.ts b/modules/@angular/platform-browser/testing/benchmark_util.ts deleted file mode 100644 index d111fb7b10..0000000000 --- a/modules/@angular/platform-browser/testing/benchmark_util.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - - -import {document, window} from './facade/browser'; -import {NumberWrapper, isBlank} from './facade/lang'; -import {BrowserDomAdapter} from './private_import_platform-browser'; - -var DOM = new BrowserDomAdapter(); - -export function getIntParameter(name: string) { - return NumberWrapper.parseInt(getStringParameter(name), 10); -} - -export function getStringParameter(name: string) { - var els = DOM.querySelectorAll(document, `input[name="${name}"]`); - var value: any /** TODO #9100 */; - var el: any /** TODO #9100 */; - - for (var i = 0; i < els.length; i++) { - el = els[i]; - var type = DOM.type(el); - if ((type != 'radio' && type != 'checkbox') || DOM.getChecked(el)) { - value = DOM.getValue(el); - break; - } - } - - if (isBlank(value)) { - throw new Error(`Could not find and input field with name ${name}`); - } - - return value; -} - -export function bindAction(selector: string, callback: Function) { - var el = DOM.querySelector(document, selector); - DOM.on(el, 'click', function(_: any /** TODO #9100 */) { callback(); }); -} - -export function microBenchmark( - name: any /** TODO #9100 */, iterationCount: any /** TODO #9100 */, - callback: any /** TODO #9100 */) { - var durationName = `${name}/${iterationCount}`; - window.console.time(durationName); - callback(); - window.console.timeEnd(durationName); -} - -export function windowProfile(name: string): void { - (window.console).profile(name); -} - -export function windowProfileEnd(name: string): void { - (window.console).profileEnd(name); -} diff --git a/modules/@angular/router/src/router.ts b/modules/@angular/router/src/router.ts index 34a76f0ffc..791527b39d 100644 --- a/modules/@angular/router/src/router.ts +++ b/modules/@angular/router/src/router.ts @@ -546,7 +546,7 @@ export class Router { resolvePromise(false); } }, - (e: any) => { + (e: any) => { if (e instanceof NavigationCancelingError) { this.navigated = true; this.routerEvents.next( diff --git a/modules/benchmarks/e2e_test/tree_perf.ts b/modules/benchmarks/e2e_test/tree_perf.ts index 154c339368..0c5c60dc88 100644 --- a/modules/benchmarks/e2e_test/tree_perf.ts +++ b/modules/benchmarks/e2e_test/tree_perf.ts @@ -8,58 +8,52 @@ import {runBenchmark, verifyNoBrowserErrors} from 'e2e_util/perf_util'; -describe('tree benchmark', () => { +describe('tree benchmark perf', () => { afterEach(verifyNoBrowserErrors); - it('should work for the baseline', (done) => { - runBenchmark({ + it('should run for ng2', (done) => { + runTreeBenchmark({ + id: 'deepTree.ng2', + url: 'all/benchmarks/src/tree/ng2/index.html', + }).then(done, done.fail); + }); + + it('should run for the baseline', (done) => { + runTreeBenchmark({ id: 'deepTree.baseline', url: 'all/benchmarks/src/tree/baseline/index.html', ignoreBrowserSynchronization: true, - params: [{name: 'depth', value: 9}], - work: () => { - $('#createDom').click(); - $('#destroyDom').click(); - } }).then(done, done.fail); }); - it('should work for ng2', (done) => { - runBenchmark({ - id: 'deepTree.ng2', - url: 'all/benchmarks/src/tree/ng2/index.html', - params: [{name: 'depth', value: 9}], - work: () => { - $('#createDom').click(); - $('#destroyDom').click(); - } - }).then(done, done.fail); - }); - - it('should work for polymer binary tree', (done) => { - runBenchmark({ + it('should run for polymer binary tree', (done) => { + runTreeBenchmark({ id: 'deepTree.polymer', url: 'all/benchmarks/src/tree/polymer/index.html', ignoreBrowserSynchronization: true, - params: [{name: 'depth', value: 9}], - work: () => { - $('#createDom').click(); - $('#destroyDom').click(); - } }).then(done, done.fail); }); - it('should work for polymer leaves', (done) => { - runBenchmark({ + it('should run for polymer leaves', (done) => { + runTreeBenchmark({ id: 'deepTree.polymerLeaves', url: 'all/benchmarks/src/tree/polymer_leaves/index.html', ignoreBrowserSynchronization: true, + }).then(done, done.fail); + }); + + function runTreeBenchmark( + config: {id: string, url: string, ignoreBrowserSynchronization?: boolean}) { + return runBenchmark({ + id: config.id, + url: config.url, + ignoreBrowserSynchronization: config.ignoreBrowserSynchronization, params: [{name: 'depth', value: 9}], work: () => { $('#createDom').click(); $('#destroyDom').click(); } - }).then(done, done.fail); - }); + }); + } }); diff --git a/modules/benchmarks/e2e_test/tree_spec.ts b/modules/benchmarks/e2e_test/tree_spec.ts index fc7a635ffb..e5fcb8eb45 100644 --- a/modules/benchmarks/e2e_test/tree_spec.ts +++ b/modules/benchmarks/e2e_test/tree_spec.ts @@ -8,45 +8,42 @@ import {openBrowser, verifyNoBrowserErrors} from 'e2e_util/e2e_util'; -const useBundles = false; - -describe('tree benchmark', () => { +describe('tree benchmark spec', () => { afterEach(verifyNoBrowserErrors); + it('should work for ng2', () => { + testTreeBenchmark({ + url: 'all/benchmarks/src/tree/ng2/index.html', + }); + }); + it('should work for the baseline', () => { - openBrowser({ + testTreeBenchmark({ url: 'all/benchmarks/src/tree/baseline/index.html', ignoreBrowserSynchronization: true, }); - $('#createDom').click(); - expect($('baseline').getText()).toContain('0'); - }); - - it('should work for ng2', () => { - openBrowser({ - url: 'all/benchmarks/src/tree/ng2/index.html', - }); - $('#createDom').click(); - expect($('app').getText()).toContain('0'); }); it('should work for polymer binary tree', () => { - openBrowser({ + testTreeBenchmark({ url: 'all/benchmarks/src/tree/polymer/index.html', ignoreBrowserSynchronization: true, }); - $('#createDom').click(); - expect($('#app').getText()).toContain('0'); }); it('should work for polymer leaves', () => { - openBrowser({ + testTreeBenchmark({ url: 'all/benchmarks/src/tree/polymer_leaves/index.html', ignoreBrowserSynchronization: true, }); - $('#createDom').click(); - expect($('#app').getText()).toContain('0'); }); + function testTreeBenchmark(openConfig: {url: string, ignoreBrowserSynchronization?: boolean}) { + openBrowser(openConfig); + $('#createDom').click(); + expect($('#root').getText()).toContain('0'); + $('#destroyDom').click(); + expect($('#root').getText()).toEqual(''); + } }); diff --git a/modules/benchmarks/src/bootstrap.ts b/modules/benchmarks/src/bootstrap_ng2.ts similarity index 68% rename from modules/benchmarks/src/bootstrap.ts rename to modules/benchmarks/src/bootstrap_ng2.ts index f5cc16cc12..b824af7f2d 100644 --- a/modules/benchmarks/src/bootstrap.ts +++ b/modules/benchmarks/src/bootstrap_ng2.ts @@ -6,8 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ - -(function(global: any /** TODO #9100 */) { +(function(global: any) { writeScriptTag('/all/benchmarks/vendor/core.js'); writeScriptTag('/all/benchmarks/vendor/zone.js'); @@ -18,13 +17,12 @@ (global).benchmarksBootstrap = benchmarksBootstrap; function benchmarksBootstrap() { - urlParamsToForm(); // check query param var useBundles = location.search.indexOf('bundles=false') == -1; if (useBundles) { System.config({ + defaultJSExtensions: true, map: { - 'index': 'index.js', '@angular/core': '/packages-dist/core/bundles/core.umd.js', '@angular/common': '/packages-dist/common/bundles/common.umd.js', '@angular/forms': '/packages-dist/forms/bundles/forms.umd.js', @@ -40,8 +38,6 @@ 'rxjs': '/all/benchmarks/vendor/rxjs' }, packages: { - 'app': {defaultExtension: 'js'}, - '../app': {defaultExtension: 'js'}, '@angular/core/src/facade': {defaultExtension: 'js'}, 'rxjs': {defaultExtension: 'js'} } @@ -51,14 +47,9 @@ 'Not using the Angular bundles. Don\'t use this configuration for e2e/performance tests!'); System.config({ - map: { - 'index': 'index.js', - '@angular': '/all/@angular', - 'rxjs': '/all/benchmarks/vendor/rxjs' - }, + defaultJSExtensions: true, + map: {'@angular': '/all/@angular', 'rxjs': '/all/benchmarks/vendor/rxjs'}, packages: { - 'app': {defaultExtension: 'js'}, - '../app': {defaultExtension: 'js'}, '@angular/core': {main: 'index.js', defaultExtension: 'js'}, '@angular/compiler': {main: 'index.js', defaultExtension: 'js'}, '@angular/router': {main: 'index.js', defaultExtension: 'js'}, @@ -72,37 +63,11 @@ }); } - // BOOTSTRAP the app! - System.import('index').then(function(m: any /** TODO #9100 */) { - m.main(); - }, console.error.bind(console)); + System.import('index').then(function(m: any) { m.main(); }, console.error.bind(console)); } - - function writeScriptTag(scriptUrl: any /** TODO #9100 */, onload?: any /** TODO #9100 */) { + function writeScriptTag(scriptUrl: string, onload?: string) { document.write(``); } - - // helper script that will read out the url parameters - // and store them in appropriate form fields on the page - function urlParamsToForm() { - var regex = /(\w+)=(\w+)/g; - var search = decodeURIComponent(location.search); - var match: any[]; - while (match = regex.exec(search)) { - var name = match[1]; - var value = match[2]; - var els = document.querySelectorAll('input[name="' + name + '"]'); - var el: any; - for (var i = 0; i < els.length; i++) { - el = els[i]; - if (el.type === 'radio' || el.type === 'checkbox') { - el.checked = el.value === value; - } else { - el.value = value; - } - } - } - } }(window)); diff --git a/modules/benchmarks/src/bootstrap_polymer.ts b/modules/benchmarks/src/bootstrap_polymer.ts new file mode 100644 index 0000000000..d6d1cf56e5 --- /dev/null +++ b/modules/benchmarks/src/bootstrap_polymer.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +(function(global: any) { + + writeScriptTag('/all/benchmarks/vendor/core.js'); + writeScriptTag('/all/benchmarks/vendor/system.src.js', 'benchmarksBootstrap()'); + + (global).benchmarksBootstrap = benchmarksBootstrap; + + function benchmarksBootstrap() { + System.config({defaultJSExtensions: true}); + + // BOOTSTRAP the app! + System.import('index').then(function(m: any) { m.main(); }, console.error.bind(console)); + } + + function writeScriptTag(scriptUrl: string, onload?: string) { + document.write(``); + } +}(window)); diff --git a/modules/benchmarks/src/index.html b/modules/benchmarks/src/index.html deleted file mode 100644 index 474efd51ca..0000000000 --- a/modules/benchmarks/src/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - diff --git a/modules/benchmarks/src/tree/app/util.ts b/modules/benchmarks/src/tree/app/util.ts deleted file mode 100644 index 5d39f432d8..0000000000 --- a/modules/benchmarks/src/tree/app/util.ts +++ /dev/null @@ -1,67 +0,0 @@ -import {getIntParameter, windowProfile, windowProfileEnd} from '@angular/platform-browser/testing/benchmark_util'; - -export class TreeNode { - constructor(public value: string, public left: TreeNode, public right: TreeNode) {} -} - -let treeCreateCount: number; -let maxDepth: number; -let numberData: string[]; -let charData: string[]; - -init(); - -function init() { - maxDepth = getIntParameter('depth'); - treeCreateCount = 0; - numberData = []; - charData = []; - for (let i = 0; i < maxDepth; i++) { - numberData.push(i.toString()); - charData.push(String.fromCharCode('A'.charCodeAt(0) + i)); - } -} - -function _buildTree(values: string[], curDepth: number = 0): TreeNode { - if (maxDepth === curDepth) return new TreeNode('', null, null); - return new TreeNode( - values[curDepth], _buildTree(values, curDepth + 1), _buildTree(values, curDepth + 1)); -} - -export function emptyTree(): TreeNode { - return new TreeNode('', null, null); -} - -export function buildTree(): TreeNode { - treeCreateCount++; - return _buildTree(treeCreateCount % 2 ? numberData : charData); -} - -export function profile(create: () => void, destroy: () => void, name: string) { - return function() { - windowProfile(name + ' w GC'); - var duration = 0; - var count = 0; - while (count++ < 150) { - (window)['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`); - }; -} \ No newline at end of file diff --git a/modules/benchmarks/src/tree/baseline/index.html b/modules/benchmarks/src/tree/baseline/index.html index e4ae515dda..71af2520e0 100644 --- a/modules/benchmarks/src/tree/baseline/index.html +++ b/modules/benchmarks/src/tree/baseline/index.html @@ -19,9 +19,9 @@

- +
- + \ No newline at end of file diff --git a/modules/benchmarks/src/tree/baseline/index.ts b/modules/benchmarks/src/tree/baseline/index.ts index c82eb4025f..96f1e3a967 100644 --- a/modules/benchmarks/src/tree/baseline/index.ts +++ b/modules/benchmarks/src/tree/baseline/index.ts @@ -1,23 +1,18 @@ -import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter'; -import {bindAction} from '@angular/platform-browser/testing/benchmark_util'; - -import {TreeNode, buildTree, emptyTree, profile} from '../app/util'; - -import {BaseLineTreeComponent} from './app/tree'; +import {bindAction, profile} from '../../util'; +import {TreeNode, buildTree, emptyTree} from '../util'; +import {BaseLineTreeComponent} from './tree'; export function main() { var app: BaseLineTreeComponent; - function destroyDom() { app.update(emptyTree()); } + function destroyDom() { app.update(emptyTree); } function createDom() { app.update(buildTree()); } function noop() {} function init() { - BrowserDomAdapter.makeCurrent(); - const tree = document.createElement('tree'); - document.querySelector('baseline').appendChild(tree); + const tree: any = document.querySelector('tree'); app = new BaseLineTreeComponent(tree); bindAction('#destroyDom', destroyDom); diff --git a/modules/benchmarks/src/tree/baseline/app/tree.ts b/modules/benchmarks/src/tree/baseline/tree.ts similarity index 83% rename from modules/benchmarks/src/tree/baseline/app/tree.ts rename to modules/benchmarks/src/tree/baseline/tree.ts index 28800df07d..3e500ecd06 100644 --- a/modules/benchmarks/src/tree/baseline/app/tree.ts +++ b/modules/benchmarks/src/tree/baseline/tree.ts @@ -1,7 +1,11 @@ -import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; -import {TreeNode} from '../../app/util'; +import {__platform_browser_private__} from '@angular/platform-browser'; +import {TreeNode} from '../util'; -// http://jsperf.com/nextsibling-vs-childnodes +// Note: We are using the DomAdapter also in the Baseline +// so that Ng2 can actually reach the baseline. Once Ng2 is able to generate +// code that does not use the DomAdapter any more, we should remove this. +__platform_browser_private__.initDomAdapter(); +const getDOM = __platform_browser_private__.getDOM; const BASELINE_TREE_TEMPLATE = document.createElement('template'); BASELINE_TREE_TEMPLATE.innerHTML = diff --git a/modules/benchmarks/src/tree/ng2/index.html b/modules/benchmarks/src/tree/ng2/index.html index 7c7f30edd9..231eb44f3e 100644 --- a/modules/benchmarks/src/tree/ng2/index.html +++ b/modules/benchmarks/src/tree/ng2/index.html @@ -19,9 +19,9 @@

- +
- + \ No newline at end of file diff --git a/modules/benchmarks/src/tree/ng2/index.ts b/modules/benchmarks/src/tree/ng2/index.ts index c47a8ea5ca..a7f9c46bd9 100644 --- a/modules/benchmarks/src/tree/ng2/index.ts +++ b/modules/benchmarks/src/tree/ng2/index.ts @@ -1,23 +1,22 @@ -import {NgModule, enableProdMode} from '@angular/core'; -import {ApplicationRef} from '@angular/core/src/application_ref'; +import {ApplicationRef, NgModule, enableProdMode} from '@angular/core'; import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; -import {bindAction, windowProfile, windowProfileEnd} from '@angular/platform-browser/testing/benchmark_util'; -import {TreeNode, buildTree, emptyTree, profile} from '../app/util'; +import {bindAction, profile} from '../../util'; +import {TreeNode, buildTree, emptyTree} from '../util'; -import {AppComponent, AppModule} from './app/tree'; +import {AppModule, TreeComponent} from './tree'; export function main() { - var app: AppComponent; + var tree: TreeComponent; var appRef: ApplicationRef; function destroyDom() { - app.initData = emptyTree(); + tree.data = emptyTree; appRef.tick(); } function createDom() { - app.initData = buildTree(); + tree.data = buildTree(); appRef.tick(); } @@ -29,7 +28,7 @@ export function main() { var injector = ref.injector; appRef = injector.get(ApplicationRef); - app = appRef.components[0].instance; + tree = appRef.components[0].instance; bindAction('#destroyDom', destroyDom); bindAction('#createDom', createDom); bindAction('#updateDomProfile', profile(createDom, noop, 'ng2-update')); diff --git a/modules/benchmarks/src/tree/ng2/app/tree.ts b/modules/benchmarks/src/tree/ng2/tree.ts similarity index 51% rename from modules/benchmarks/src/tree/ng2/app/tree.ts rename to modules/benchmarks/src/tree/ng2/tree.ts index 5a8506ac2e..a5608bba00 100644 --- a/modules/benchmarks/src/tree/ng2/app/tree.ts +++ b/modules/benchmarks/src/tree/ng2/tree.ts @@ -1,7 +1,7 @@ import {Component, NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; -import {TreeNode, emptyTree} from '../../app/util'; +import {TreeNode, emptyTree} from '../util'; @Component({ selector: 'tree', @@ -9,20 +9,10 @@ import {TreeNode, emptyTree} from '../../app/util'; template: ` {{data.value}} ` }) -class TreeComponent { - data: TreeNode; +export class TreeComponent { + data: TreeNode = emptyTree; } -@Component({selector: 'app', template: ``}) -export class AppComponent { - initData: TreeNode; - constructor() { this.initData = emptyTree(); } -} - -@NgModule({ - imports: [BrowserModule], - bootstrap: [AppComponent], - declarations: [TreeComponent, AppComponent] -}) +@NgModule({imports: [BrowserModule], bootstrap: [TreeComponent], declarations: [TreeComponent]}) export class AppModule { } diff --git a/modules/benchmarks/src/tree/polymer/index.html b/modules/benchmarks/src/tree/polymer/index.html index e9052aa214..6da43b09c7 100644 --- a/modules/benchmarks/src/tree/polymer/index.html +++ b/modules/benchmarks/src/tree/polymer/index.html @@ -20,10 +20,10 @@

- +
- + diff --git a/modules/benchmarks/src/tree/polymer/index.ts b/modules/benchmarks/src/tree/polymer/index.ts index a4e53525c0..ddc9bab9a1 100644 --- a/modules/benchmarks/src/tree/polymer/index.ts +++ b/modules/benchmarks/src/tree/polymer/index.ts @@ -1,14 +1,13 @@ -import {bindAction} from '@angular/platform-browser/testing/benchmark_util'; - -import {buildTree, emptyTree} from '../app/util'; +import {bindAction} from '../../util'; +import {buildTree, emptyTree} from '../util'; declare var Polymer: any; export function main() { const rootEl: any = document.querySelector('binary-tree'); - rootEl.data = emptyTree(); + rootEl.data = emptyTree; - function destroyDom() { rootEl.data = emptyTree(); } + function destroyDom() { rootEl.data = emptyTree; } function createDom() { rootEl.data = buildTree(); } diff --git a/modules/benchmarks/src/tree/polymer_leaves/index.html b/modules/benchmarks/src/tree/polymer_leaves/index.html index b15d3814f8..5ed31cde32 100644 --- a/modules/benchmarks/src/tree/polymer_leaves/index.html +++ b/modules/benchmarks/src/tree/polymer_leaves/index.html @@ -13,17 +13,17 @@ -

Polymer tree benchmark

+

Polymer leaves benchmark

- +
- + diff --git a/modules/benchmarks/src/tree/polymer_leaves/index.ts b/modules/benchmarks/src/tree/polymer_leaves/index.ts index d83ce6657d..7c2617f9e2 100644 --- a/modules/benchmarks/src/tree/polymer_leaves/index.ts +++ b/modules/benchmarks/src/tree/polymer_leaves/index.ts @@ -1,13 +1,12 @@ -import {bindAction} from '@angular/platform-browser/testing/benchmark_util'; - -import {TreeNode, buildTree, emptyTree} from '../app/util'; +import {bindAction} from '../../util'; +import {TreeNode, buildTree, emptyTree} from '../util'; declare var Polymer: any; export function main() { const rootEl: any = document.querySelector('binary-tree'); - rootEl.data = emptyTree(); + rootEl.data = emptyTree; function destroyDom() { while (rootEl.firstChild) rootEl.removeChild(rootEl.firstChild); diff --git a/modules/benchmarks/src/tree/util.ts b/modules/benchmarks/src/tree/util.ts new file mode 100644 index 0000000000..37e135b040 --- /dev/null +++ b/modules/benchmarks/src/tree/util.ts @@ -0,0 +1,36 @@ +import {getIntParameter} from '../util'; + +export class TreeNode { + constructor(public value: string, public left: TreeNode, public right: TreeNode) {} +} + +let treeCreateCount: number; +let maxDepth: number; +let numberData: string[]; +let charData: string[]; + +init(); + +function init() { + maxDepth = getIntParameter('depth'); + treeCreateCount = 0; + numberData = []; + charData = []; + for (let i = 0; i < maxDepth; i++) { + numberData.push(i.toString()); + charData.push(String.fromCharCode('A'.charCodeAt(0) + i)); + } +} + +function _buildTree(values: string[], curDepth: number = 0): TreeNode { + if (maxDepth === curDepth) return new TreeNode('', null, null); + return new TreeNode( + values[curDepth], _buildTree(values, curDepth + 1), _buildTree(values, curDepth + 1)); +} + +export const emptyTree = new TreeNode('', null, null); + +export function buildTree(): TreeNode { + treeCreateCount++; + return _buildTree(treeCreateCount % 2 ? numberData : charData); +} diff --git a/modules/benchmarks/src/util.ts b/modules/benchmarks/src/util.ts new file mode 100644 index 0000000000..828d7a340a --- /dev/null +++ b/modules/benchmarks/src/util.ts @@ -0,0 +1,90 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +urlParamsToForm(); + +export function getIntParameter(name: string) { + return parseInt(getStringParameter(name), 10); +} + +export function getStringParameter(name: string) { + var els = document.querySelectorAll(`input[name="${name}"]`); + var value: any; + var el: any; + + for (var i = 0; i < els.length; i++) { + el = els[i]; + var type = el.type; + if ((type != 'radio' && type != 'checkbox') || el.checked) { + value = el.value; + break; + } + } + + if (value == null) { + throw new Error(`Could not find and input field with name ${name}`); + } + + return value; +} + +export function bindAction(selector: string, callback: () => void) { + document.querySelector(selector).addEventListener('click', callback); +} + + +export function profile(create: () => void, destroy: () => void, name: string) { + return function() { + window.console.profile(name + ' w GC'); + var duration = 0; + var count = 0; + while (count++ < 150) { + (window)['gc'](); + var start = window.performance.now(); + create(); + duration += window.performance.now() - start; + destroy(); + } + window.console.profileEnd(); + window.console.log(`Iterations: ${count}; time: ${duration / count} ms / iteration`); + + window.console.profile(name + ' w/o GC'); + duration = 0; + count = 0; + while (count++ < 150) { + var start = window.performance.now(); + create(); + duration += window.performance.now() - start; + destroy(); + } + window.console.profileEnd(); + window.console.log(`Iterations: ${count}; time: ${duration / count} ms / iteration`); + }; +} + +// helper script that will read out the url parameters +// and store them in appropriate form fields on the page +function urlParamsToForm() { + var regex = /(\w+)=(\w+)/g; + var search = decodeURIComponent(location.search); + var match: any[]; + while (match = regex.exec(search)) { + var name = match[1]; + var value = match[2]; + var els = document.querySelectorAll('input[name="' + name + '"]'); + var el: any; + for (var i = 0; i < els.length; i++) { + el = els[i]; + if (el.type === 'radio' || el.type === 'checkbox') { + el.checked = el.value === value; + } else { + el.value = value; + } + } + } +} \ No newline at end of file diff --git a/modules/e2e_util/e2e_util.ts b/modules/e2e_util/e2e_util.ts index 9ac0250940..5218716d64 100644 --- a/modules/e2e_util/e2e_util.ts +++ b/modules/e2e_util/e2e_util.ts @@ -40,6 +40,9 @@ export function openBrowser(config: { params.forEach((param) => { urlParams.push(param.name + '=' + param.value); }); var url = encodeURI(config.url + '?' + urlParams.join('&')); browser.get(url); + if (config.ignoreBrowserSynchronization) { + browser.sleep(500); + } } /** diff --git a/protractor-e2e.conf.js b/protractor-e2e.conf.js index db3707f30c..35999654de 100644 --- a/protractor-e2e.conf.js +++ b/protractor-e2e.conf.js @@ -16,6 +16,11 @@ var BROWSER_OPTIONS = { }; exports.config = { + onPrepare: function() { + beforeEach(function() { + browser.ignoreSynchronization = false; + }); + }, allScriptsTimeout: 11000, specs: [ 'dist/all/**/e2e_test/**/*_spec.js' diff --git a/protractor-perf.conf.js b/protractor-perf.conf.js index 9b4c5d60e5..97b250225b 100644 --- a/protractor-perf.conf.js +++ b/protractor-perf.conf.js @@ -3,7 +3,7 @@ require('./dist/all/e2e_util/perf_util').readCommandLine(); var CHROME_OPTIONS = { - 'args': ['--js-flags=--expose-gc'], + 'args': ['--js-flags=--expose-gc', '--no-sandbox'], 'perfLoggingPrefs': { 'traceCategories': 'v8,blink.console,devtools.timeline,disabled-by-default-devtools.timeline' } @@ -21,7 +21,6 @@ var BROWSER_CAPS = { ChromeOnTravis: { browserName: 'chrome', chromeOptions: mergeInto(CHROME_OPTIONS, { - 'args': ['--no-sandbox'], 'binary': process.env.CHROME_BIN }), loggingPrefs: { @@ -32,6 +31,11 @@ var BROWSER_CAPS = { }; exports.config = { + onPrepare: function() { + beforeEach(function() { + browser.ignoreSynchronization = false; + }); + }, restartBrowserBetweenTests: true, allScriptsTimeout: 11000, specs: [ diff --git a/scripts/ci-lite/install.sh b/scripts/ci-lite/install.sh index 8347aab9a4..d0bd154637 100755 --- a/scripts/ci-lite/install.sh +++ b/scripts/ci-lite/install.sh @@ -58,7 +58,7 @@ echo 'travis_fold:end:install.browserstack' # node tools/chromedriverpatch.js $(npm bin)/webdriver-manager update -# TODO: install bower packages -# bower install +# install bower packages +$(npm bin)/bower install echo 'travis_fold:end:INSTALL'