From 24facdea2d6a5721a0f1c7d84032efe0f58b4f5d Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Tue, 18 Oct 2016 15:45:42 -0700 Subject: [PATCH] feat(benchmark): add large form benchmark This benchmark tracks the generated file size for large forms as well as the time to create and destroy many form fields. --- modules/benchmarks/e2e_test/largeform_perf.ts | 52 ++++++++++++ modules/benchmarks/e2e_test/largeform_spec.ts | 34 ++++++++ modules/benchmarks/src/largeform/README.md | 7 ++ modules/benchmarks/src/largeform/ng2/app.ts | 83 +++++++++++++++++++ .../benchmarks/src/largeform/ng2/index.html | 29 +++++++ modules/benchmarks/src/largeform/ng2/index.ts | 10 +++ .../benchmarks/src/largeform/ng2/index_aot.ts | 8 ++ modules/benchmarks/src/largeform/ng2/init.ts | 32 +++++++ 8 files changed, 255 insertions(+) create mode 100644 modules/benchmarks/e2e_test/largeform_perf.ts create mode 100644 modules/benchmarks/e2e_test/largeform_spec.ts create mode 100644 modules/benchmarks/src/largeform/README.md create mode 100644 modules/benchmarks/src/largeform/ng2/app.ts create mode 100644 modules/benchmarks/src/largeform/ng2/index.html create mode 100644 modules/benchmarks/src/largeform/ng2/index.ts create mode 100644 modules/benchmarks/src/largeform/ng2/index_aot.ts create mode 100644 modules/benchmarks/src/largeform/ng2/init.ts diff --git a/modules/benchmarks/e2e_test/largeform_perf.ts b/modules/benchmarks/e2e_test/largeform_perf.ts new file mode 100644 index 0000000000..310a86d4f0 --- /dev/null +++ b/modules/benchmarks/e2e_test/largeform_perf.ts @@ -0,0 +1,52 @@ +/** + * @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 {runBenchmark, verifyNoBrowserErrors} from 'e2e_util/perf_util'; + +interface Worker { + id: string; + prepare?(): void; + work(): void; +} + +const CreateAndDestroyWorker: Worker = { + id: 'createDestroy', + work: () => { + $('#createDom').click(); + $('#destroyDom').click(); + } +}; + +describe('largeform benchmark perf', () => { + + afterEach(verifyNoBrowserErrors); + + [CreateAndDestroyWorker].forEach((worker) => { + describe(worker.id, () => { + it('should run for ng2', (done) => { + runLargeFormBenchmark({ + id: `largeform.ng2.${worker.id}`, + url: 'all/benchmarks/src/largeform/ng2/index.html', + worker: worker + }).then(done, done.fail); + }); + }); + }); + + function runLargeFormBenchmark( + config: {id: string, url: string, ignoreBrowserSynchronization?: boolean, worker: Worker}) { + return runBenchmark({ + id: config.id, + url: config.url, + params: [{name: 'copies', value: 8}], + ignoreBrowserSynchronization: config.ignoreBrowserSynchronization, + prepare: config.worker.prepare, + work: config.worker.work + }); + } +}); diff --git a/modules/benchmarks/e2e_test/largeform_spec.ts b/modules/benchmarks/e2e_test/largeform_spec.ts new file mode 100644 index 0000000000..ace91dc007 --- /dev/null +++ b/modules/benchmarks/e2e_test/largeform_spec.ts @@ -0,0 +1,34 @@ +/** + * @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 {openBrowser, verifyNoBrowserErrors} from 'e2e_util/e2e_util'; + +describe('largeform benchmark spec', () => { + + afterEach(verifyNoBrowserErrors); + + it('should work for ng2', () => { + testLargeformBenchmark({ + url: 'all/benchmarks/src/largeform/ng2/index.html', + }); + }); + + function testLargeformBenchmark( + openConfig: {url: string, ignoreBrowserSynchronization?: boolean}) { + openBrowser({ + url: openConfig.url, + params: [{name: 'copies', value: 1}], + ignoreBrowserSynchronization: openConfig.ignoreBrowserSynchronization, + }); + $('#createDom').click(); + expect(element.all(By.css('input[name=value0]')).get(0).getAttribute('value')) + .toBe('someValue0'); + $('#destroyDom').click(); + expect(element.all(By.css('input[name=value0]')).count()).toBe(0); + } +}); diff --git a/modules/benchmarks/src/largeform/README.md b/modules/benchmarks/src/largeform/README.md new file mode 100644 index 0000000000..152fc1bba9 --- /dev/null +++ b/modules/benchmarks/src/largeform/README.md @@ -0,0 +1,7 @@ +# Large Form Benchmark + +Purpose: + +- Track generated file size for a big form +- Track time for creation / destruction of form widgets, + as they are more complex (e.g. include event listeners, host bindings, ...) diff --git a/modules/benchmarks/src/largeform/ng2/app.ts b/modules/benchmarks/src/largeform/ng2/app.ts new file mode 100644 index 0000000000..a35864499c --- /dev/null +++ b/modules/benchmarks/src/largeform/ng2/app.ts @@ -0,0 +1,83 @@ +import {Component, NgModule} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {BrowserModule} from '@angular/platform-browser'; + +@Component({ + selector: 'app', + template: `
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
` +}) +export class AppComponent { + copies: number[] = []; + values: string[] = []; + constructor() { + for (var i = 0; i < 50; i++) { + this.values[i] = `someValue${i}`; + } + } + + setCopies(count: number) { + this.copies = []; + for (var i = 0; i < count; i++) { + this.copies.push(i); + } + } +} + +@NgModule({ + imports: [BrowserModule, FormsModule], + bootstrap: [AppComponent], + declarations: [AppComponent] +}) +export class AppModule { +} diff --git a/modules/benchmarks/src/largeform/ng2/index.html b/modules/benchmarks/src/largeform/ng2/index.html new file mode 100644 index 0000000000..02796b44c6 --- /dev/null +++ b/modules/benchmarks/src/largeform/ng2/index.html @@ -0,0 +1,29 @@ + + + +

Params

+
+ Copies: + +
+ +
+ +

Ng2 Large Form Benchmark

+

+ + + +

+ +
+ Loading... +
+ + + + diff --git a/modules/benchmarks/src/largeform/ng2/index.ts b/modules/benchmarks/src/largeform/ng2/index.ts new file mode 100644 index 0000000000..9ff4055b14 --- /dev/null +++ b/modules/benchmarks/src/largeform/ng2/index.ts @@ -0,0 +1,10 @@ +import {enableProdMode} from '@angular/core'; +import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; + +import {AppModule} from './app'; +import {init} from './init'; + +export function main() { + enableProdMode(); + platformBrowserDynamic().bootstrapModule(AppModule).then(init); +} diff --git a/modules/benchmarks/src/largeform/ng2/index_aot.ts b/modules/benchmarks/src/largeform/ng2/index_aot.ts new file mode 100644 index 0000000000..a42d3aa1b3 --- /dev/null +++ b/modules/benchmarks/src/largeform/ng2/index_aot.ts @@ -0,0 +1,8 @@ +import {enableProdMode} from '@angular/core'; +import {platformBrowser} from '@angular/platform-browser'; + +import {AppModuleNgFactory} from './app.ngfactory'; +import {init} from './init'; + +enableProdMode(); +platformBrowser().bootstrapModuleFactory(AppModuleNgFactory).then(init); diff --git a/modules/benchmarks/src/largeform/ng2/init.ts b/modules/benchmarks/src/largeform/ng2/init.ts new file mode 100644 index 0000000000..bf66b058c6 --- /dev/null +++ b/modules/benchmarks/src/largeform/ng2/init.ts @@ -0,0 +1,32 @@ +import {ApplicationRef, NgModuleRef} from '@angular/core'; + +import {bindAction, getIntParameter, profile} from '../../util'; + +import {AppComponent, AppModule} from './app'; + +const copies = getIntParameter('copies'); + +export function init(moduleRef: NgModuleRef) { + let app: AppComponent; + let appRef: ApplicationRef; + + function destroyDom() { + app.setCopies(0); + appRef.tick(); + } + + function createDom() { + app.setCopies(copies); + appRef.tick(); + } + + function noop() {} + + const injector = moduleRef.injector; + appRef = injector.get(ApplicationRef); + + app = appRef.components[0].instance; + bindAction('#destroyDom', destroyDom); + bindAction('#createDom', createDom); + bindAction('#createDomProfile', profile(createDom, destroyDom, 'create')); +}