refactor(benchmarks): make tree benchmark work again
This commit is contained in:

committed by
Victor Berchet

parent
5ff14de1f3
commit
61002733bc
23
modules/benchmarks/src/old/compiler/compiler_benchmark.html
Normal file
23
modules/benchmarks/src/old/compiler/compiler_benchmark.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
<form>
|
||||
Elements:
|
||||
<input type="number" name="elements" placeholder="elements" value="50">
|
||||
<br>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
|
||||
<h2>Actions</h2>
|
||||
<p>
|
||||
<button id="compileWithBindings">CompileWithBindings</button>
|
||||
<button id="compileNoBindings">CompileNoBindings</button>
|
||||
</p>
|
||||
|
||||
<app></app>
|
||||
$SCRIPTS$
|
||||
|
||||
</body>
|
||||
</html>
|
184
modules/benchmarks/src/old/compiler/compiler_benchmark.ts
Normal file
184
modules/benchmarks/src/old/compiler/compiler_benchmark.ts
Normal file
@ -0,0 +1,184 @@
|
||||
import {bootstrap} from '@angular/platform-browser';
|
||||
import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter';
|
||||
import {DOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {PromiseWrapper} from '@angular/facade/src/async';
|
||||
import {ListWrapper, Map, MapWrapper} from '@angular/facade/src/collection';
|
||||
import {DateWrapper, Type, print, isPresent} from '@angular/facade/src/lang';
|
||||
|
||||
import {
|
||||
ComponentResolver,
|
||||
Component,
|
||||
Directive,
|
||||
ViewContainerRef,
|
||||
} from '@angular/core';
|
||||
|
||||
import {ViewMetadata} from '@angular/core/src/metadata/view';
|
||||
|
||||
import {CompilerConfig, DirectiveResolver} from '@angular/compiler';
|
||||
|
||||
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
|
||||
function _createBindings(): any[] {
|
||||
var multiplyTemplatesBy = getIntParameter('elements');
|
||||
return [
|
||||
{
|
||||
provide: DirectiveResolver,
|
||||
useFactory: () => new MultiplyDirectiveResolver(
|
||||
multiplyTemplatesBy,
|
||||
[BenchmarkComponentNoBindings, BenchmarkComponentWithBindings]),
|
||||
deps: []
|
||||
},
|
||||
// Use interpretative mode as Dart does not support JIT and
|
||||
// we want to be able to compare the numbers between JS and Dart
|
||||
{provide: CompilerConfig, useValue: new CompilerConfig({genDebugInfo: false, useJit: false, logBindingUpdate: false})}
|
||||
];
|
||||
}
|
||||
|
||||
export function main() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
bootstrap(CompilerAppComponent, _createBindings())
|
||||
.then((ref) => {
|
||||
var app = ref.instance;
|
||||
bindAction('#compileNoBindings',
|
||||
measureWrapper(() => app.compileNoBindings(), 'No Bindings'));
|
||||
bindAction('#compileWithBindings',
|
||||
measureWrapper(() => app.compileWithBindings(), 'With Bindings'));
|
||||
});
|
||||
}
|
||||
|
||||
function measureWrapper(func, desc) {
|
||||
return function() {
|
||||
var begin = DateWrapper.now();
|
||||
print(`[${desc}] Begin...`);
|
||||
var onSuccess = function(_) {
|
||||
var elapsedMs = DateWrapper.toMillis(DateWrapper.now()) - DateWrapper.toMillis(begin);
|
||||
print(`[${desc}] ...done, took ${elapsedMs} ms`);
|
||||
};
|
||||
var onError = function(e) { DOM.logError(e); };
|
||||
PromiseWrapper.then(func(), onSuccess, onError);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class MultiplyDirectiveResolver extends DirectiveResolver {
|
||||
_multiplyBy: number;
|
||||
_cache = new Map<Type, ViewMetadata>();
|
||||
|
||||
constructor(multiple: number, components: Type[]) {
|
||||
super();
|
||||
this._multiplyBy = multiple;
|
||||
components.forEach(c => this._fillCache(c));
|
||||
}
|
||||
|
||||
_fillCache(component: Type) {
|
||||
var view = super.resolve(component);
|
||||
var multipliedTemplates = ListWrapper.createFixedSize(this._multiplyBy);
|
||||
for (var i = 0; i < this._multiplyBy; ++i) {
|
||||
multipliedTemplates[i] = view.template;
|
||||
}
|
||||
this._cache.set(
|
||||
component,
|
||||
new ViewMetadata({template: multipliedTemplates.join(''), directives: view.directives}));
|
||||
}
|
||||
|
||||
resolve(component: Type): ViewMetadata {
|
||||
var result = this._cache.get(component);
|
||||
return isPresent(result) ? result : super.resolve(component);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({selector: 'app', directives: [], template: ``})
|
||||
class CompilerAppComponent {
|
||||
constructor(private _compiler: ComponentResolver) {}
|
||||
compileNoBindings() {
|
||||
this._compiler.clearCache();
|
||||
return this._compiler.resolveComponent(BenchmarkComponentNoBindings);
|
||||
}
|
||||
|
||||
compileWithBindings() {
|
||||
this._compiler.clearCache();
|
||||
return this._compiler.resolveComponent(BenchmarkComponentWithBindings);
|
||||
}
|
||||
}
|
||||
|
||||
@Directive({selector: '[dir0]', inputs: ['prop: attr0']})
|
||||
class Dir0 {
|
||||
prop: any;
|
||||
}
|
||||
|
||||
@Directive({selector: '[dir1]', inputs: ['prop: attr1']})
|
||||
class Dir1 {
|
||||
prop: any;
|
||||
constructor(dir0: Dir0) {}
|
||||
}
|
||||
|
||||
@Directive({selector: '[dir2]', inputs: ['prop: attr2']})
|
||||
class Dir2 {
|
||||
prop: any;
|
||||
constructor(dir1: Dir1) {}
|
||||
}
|
||||
|
||||
@Directive({selector: '[dir3]', inputs: ['prop: attr3']})
|
||||
class Dir3 {
|
||||
prop: any;
|
||||
constructor(dir2: Dir2) {}
|
||||
}
|
||||
|
||||
@Directive({selector: '[dir4]', inputs: ['prop: attr4']})
|
||||
class Dir4 {
|
||||
prop: any;
|
||||
constructor(dir3: Dir3) {}
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'cmp-nobind',
|
||||
directives: [Dir0, Dir1, Dir2, Dir3, Dir4],
|
||||
template: `
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
<div class="class0 class1 class2 class3 class4 " nodir0="" attr0="value0" nodir1="" attr1="value1" nodir2="" attr2="value2" nodir3="" attr3="value3" nodir4="" attr4="value4">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
class BenchmarkComponentNoBindings {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cmp-withbind',
|
||||
directives: [Dir0, Dir1, Dir2, Dir3, Dir4],
|
||||
template: `
|
||||
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
|
||||
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
|
||||
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
|
||||
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
|
||||
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
|
||||
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
|
||||
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
|
||||
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
|
||||
<div class="class0 class1 class2 class3 class4 " dir0="" [attr0]="value0" dir1="" [attr1]="value1" dir2="" [attr2]="value2" dir3="" [attr3]="value3" dir4="" [attr4]="value4">
|
||||
{{inter0}}{{inter1}}{{inter2}}{{inter3}}{{inter4}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
class BenchmarkComponentWithBindings {
|
||||
value0: any;
|
||||
value1: any;
|
||||
value2: any;
|
||||
value3: any;
|
||||
value4: any;
|
||||
|
||||
inter0: any;
|
||||
inter1: any;
|
||||
inter2: any;
|
||||
inter3: any;
|
||||
inter4: any;
|
||||
}
|
23
modules/benchmarks/src/old/compiler/selector_benchmark.html
Normal file
23
modules/benchmarks/src/old/compiler/selector_benchmark.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
<form>
|
||||
Selectors:
|
||||
<input type="number" name="selectors" placeholder="selectors" value="10000">
|
||||
<br>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
|
||||
<h2>Actions</h2>
|
||||
<p>
|
||||
<button id="parse">Selector.parse</button>
|
||||
<button id="addSelectable">Selector.addSelectable</button>
|
||||
<button id="match">Selector.match</button>
|
||||
</p>
|
||||
|
||||
$SCRIPTS$
|
||||
|
||||
</body>
|
||||
</html>
|
82
modules/benchmarks/src/old/compiler/selector_benchmark.ts
Normal file
82
modules/benchmarks/src/old/compiler/selector_benchmark.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import {SelectorMatcher} from '@angular/compiler/src/selector';
|
||||
import {CssSelector} from '@angular/compiler/src/selector';
|
||||
import {StringWrapper, Math} from '@angular/facade/lang';
|
||||
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter';
|
||||
|
||||
export function main() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
var count = getIntParameter('selectors');
|
||||
|
||||
var fixedMatcher;
|
||||
var fixedSelectorStrings = [];
|
||||
var fixedSelectors = [];
|
||||
for (var i = 0; i < count; i++) {
|
||||
fixedSelectorStrings.push(randomSelector());
|
||||
}
|
||||
for (var i = 0; i < count; i++) {
|
||||
fixedSelectors.push(CssSelector.parse(fixedSelectorStrings[i]));
|
||||
}
|
||||
fixedMatcher = new SelectorMatcher();
|
||||
for (var i = 0; i < count; i++) {
|
||||
fixedMatcher.addSelectables(fixedSelectors[i], i);
|
||||
}
|
||||
|
||||
function parse() {
|
||||
var result = [];
|
||||
for (var i = 0; i < count; i++) {
|
||||
result.push(CssSelector.parse(fixedSelectorStrings[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function addSelectable() {
|
||||
var matcher = new SelectorMatcher();
|
||||
for (var i = 0; i < count; i++) {
|
||||
matcher.addSelectables(fixedSelectors[i], i);
|
||||
}
|
||||
return matcher;
|
||||
}
|
||||
|
||||
function match() {
|
||||
var matchCount = 0;
|
||||
for (var i = 0; i < count; i++) {
|
||||
fixedMatcher.match(fixedSelectors[i][0], (selector, selected) => { matchCount += selected; });
|
||||
}
|
||||
return matchCount;
|
||||
}
|
||||
|
||||
bindAction('#parse', parse);
|
||||
bindAction('#addSelectable', addSelectable);
|
||||
bindAction('#match', match);
|
||||
}
|
||||
|
||||
function randomSelector() {
|
||||
var res = randomStr(5);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
res += '.' + randomStr(5);
|
||||
}
|
||||
for (var i = 0; i < 3; i++) {
|
||||
res += '[' + randomStr(3) + '=' + randomStr(6) + ']';
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function randomStr(len) {
|
||||
var s = '';
|
||||
while (s.length < len) {
|
||||
s += randomChar();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function randomChar() {
|
||||
var n = randomNum(62);
|
||||
if (n < 10) return n.toString(); // 1-10
|
||||
if (n < 36) return StringWrapper.fromCharCode(n + 55); // A-Z
|
||||
return StringWrapper.fromCharCode(n + 61); // a-z
|
||||
}
|
||||
|
||||
function randomNum(max) {
|
||||
return Math.floor(Math.random() * max);
|
||||
}
|
34
modules/benchmarks/src/old/costs/index.html
Normal file
34
modules/benchmarks/src/old/costs/index.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
<form>
|
||||
Size:
|
||||
<input type="number" name="size" placeholder="size" value="100">
|
||||
<br>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
|
||||
<h2>Benchmarks</h2>
|
||||
<button id="reset">Reset</button>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Baseline (plain components)</td>
|
||||
<td><button id="createPlainComponents">Run</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cost of decorators</td>
|
||||
<td><button id="createComponentsWithDirectives">Run</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cost of dynamic components</td>
|
||||
<td><button id="createDynamicComponents">Run</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<app></app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
118
modules/benchmarks/src/old/costs/index.ts
Normal file
118
modules/benchmarks/src/old/costs/index.ts
Normal file
@ -0,0 +1,118 @@
|
||||
import {bootstrap} from '@angular/platform-browser';
|
||||
import {Component, Directive, DynamicComponentLoader, ViewContainerRef} from '@angular/core';
|
||||
import {NgIf, NgFor} from '@angular/common';
|
||||
import {ApplicationRef} from '@angular/core/src/application_ref';
|
||||
import {ListWrapper} from '@angular/facade/src/lang';
|
||||
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
|
||||
var testList = null;
|
||||
|
||||
export function main() {
|
||||
var size = getIntParameter('size');
|
||||
testList = ListWrapper.createFixedSize(size);
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.then((ref) => {
|
||||
var injector = ref.injector;
|
||||
var app: AppComponent = ref.instance;
|
||||
var appRef = injector.get(ApplicationRef);
|
||||
|
||||
bindAction('#reset', function() {
|
||||
app.reset();
|
||||
appRef.tick();
|
||||
});
|
||||
|
||||
// Baseline (plain components)
|
||||
bindAction('#createPlainComponents', function() {
|
||||
app.createPlainComponents();
|
||||
appRef.tick();
|
||||
});
|
||||
|
||||
// Components with decorators
|
||||
bindAction('#createComponentsWithDirectives', function() {
|
||||
app.createComponentsWithDirectives();
|
||||
appRef.tick();
|
||||
});
|
||||
|
||||
// Components with decorators
|
||||
bindAction('#createDynamicComponents', function() {
|
||||
app.createDynamicComponents();
|
||||
appRef.tick();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Component({selector: 'dummy', template: `<div></div>`})
|
||||
class DummyComponent {
|
||||
}
|
||||
|
||||
@Directive({selector: '[dummy-decorator]'})
|
||||
class DummyDirective {
|
||||
}
|
||||
|
||||
@Directive({selector: 'dynamic-dummy'})
|
||||
class DynamicDummy {
|
||||
constructor(loader: DynamicComponentLoader, location: ViewContainerRef) {
|
||||
loader.loadNextToLocation(DummyComponent, location);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
directives: [NgIf, NgFor, DummyComponent, DummyDirective, DynamicDummy],
|
||||
template: `
|
||||
<div *ngIf="testingPlainComponents">
|
||||
<dummy *ngFor="let i of list"></dummy>
|
||||
</div>
|
||||
|
||||
<div *ngIf="testingWithDirectives">
|
||||
<dummy dummy-decorator *ngFor="let i of list"></dummy>
|
||||
</div>
|
||||
|
||||
<div *ngIf="testingDynamicComponents">
|
||||
<dynamic-dummy *ngFor="let i of list"></dynamic-dummy>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
class AppComponent {
|
||||
list: any[];
|
||||
testingPlainComponents: boolean;
|
||||
testingWithDirectives: boolean;
|
||||
testingDynamicComponents: boolean;
|
||||
|
||||
constructor() { this.reset(); }
|
||||
|
||||
reset(): void {
|
||||
this.list = [];
|
||||
this.testingPlainComponents = false;
|
||||
this.testingWithDirectives = false;
|
||||
this.testingDynamicComponents = false;
|
||||
}
|
||||
|
||||
createPlainComponents(): void {
|
||||
this.list = testList;
|
||||
this.testingPlainComponents = true;
|
||||
}
|
||||
|
||||
createComponentsWithDirectives(): void {
|
||||
this.list = testList;
|
||||
this.testingWithDirectives = true;
|
||||
}
|
||||
|
||||
createDynamicComponents(): void {
|
||||
this.list = testList;
|
||||
this.testingDynamicComponents = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
class AppModule {
|
||||
}
|
25
modules/benchmarks/src/old/di/di_benchmark.html
Normal file
25
modules/benchmarks/src/old/di/di_benchmark.html
Normal file
@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
<form>
|
||||
Iterations:
|
||||
<input type="number" name="iterations" placeholder="iterations" value="20000">
|
||||
<br>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
|
||||
<h2>Actions</h2>
|
||||
<p>
|
||||
<button id="getByToken">getByToken</button>
|
||||
<button id="getByKey">getByKey</button>
|
||||
<button id="getChild">getChild</button>
|
||||
<button id="instantiate">instantiate</button>
|
||||
<button id="createVariety">createVariety</button>
|
||||
<button id="createVarietyResolved">createVarietyResolved</button>
|
||||
</div>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
118
modules/benchmarks/src/old/di/di_benchmark.ts
Normal file
118
modules/benchmarks/src/old/di/di_benchmark.ts
Normal file
@ -0,0 +1,118 @@
|
||||
import {Injectable, ReflectiveInjector, ReflectiveKey} from '@angular/core';
|
||||
import {reflector} from '@angular/core/src/reflection/reflection';
|
||||
import {ReflectionCapabilities} from '@angular/core/src/reflection/reflection_capabilities';
|
||||
import {getIntParameter, bindAction, microBenchmark} from '@angular/testing/src/benchmark_util';
|
||||
import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter';
|
||||
|
||||
var count = 0;
|
||||
|
||||
function setupReflector() {
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
}
|
||||
|
||||
export function main() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
var iterations = getIntParameter('iterations');
|
||||
|
||||
// This benchmark does not use bootstrap and needs to create a reflector
|
||||
setupReflector();
|
||||
var bindings = [A, B, C, D, E];
|
||||
var injector = ReflectiveInjector.resolveAndCreate(bindings);
|
||||
|
||||
var D_KEY = ReflectiveKey.get(D);
|
||||
var E_KEY = ReflectiveKey.get(E);
|
||||
var childInjector = injector.resolveAndCreateChild([])
|
||||
.resolveAndCreateChild([])
|
||||
.resolveAndCreateChild([])
|
||||
.resolveAndCreateChild([])
|
||||
.resolveAndCreateChild([]);
|
||||
|
||||
var variousProviders = [A, {provide: B, useClass: C}, [D, [E]], {provide: F, useValue: 6}];
|
||||
|
||||
var variousProvidersResolved = ReflectiveInjector.resolve(variousProviders);
|
||||
|
||||
function getByToken() {
|
||||
for (var i = 0; i < iterations; ++i) {
|
||||
injector.get(D);
|
||||
injector.get(E);
|
||||
}
|
||||
}
|
||||
function getByKey() {
|
||||
for (var i = 0; i < iterations; ++i) {
|
||||
injector.get(D_KEY);
|
||||
injector.get(E_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
function getChild() {
|
||||
for (var i = 0; i < iterations; ++i) {
|
||||
childInjector.get(D);
|
||||
childInjector.get(E);
|
||||
}
|
||||
}
|
||||
|
||||
function instantiate() {
|
||||
for (var i = 0; i < iterations; ++i) {
|
||||
var child = injector.resolveAndCreateChild([E]);
|
||||
child.get(E);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an injector with a variety of provider types.
|
||||
*/
|
||||
function createVariety() {
|
||||
for (var i = 0; i < iterations; ++i) {
|
||||
ReflectiveInjector.resolveAndCreate(variousProviders);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as [createVariety] but resolves providers ahead of time.
|
||||
*/
|
||||
function createVarietyResolved() {
|
||||
for (var i = 0; i < iterations; ++i) {
|
||||
ReflectiveInjector.fromResolvedProviders(variousProvidersResolved);
|
||||
}
|
||||
}
|
||||
|
||||
bindAction('#getByToken', () => microBenchmark('injectAvg', iterations, getByToken));
|
||||
bindAction('#getByKey', () => microBenchmark('injectAvg', iterations, getByKey));
|
||||
bindAction('#getChild', () => microBenchmark('injectAvg', iterations, getChild));
|
||||
bindAction('#instantiate', () => microBenchmark('injectAvg', iterations, instantiate));
|
||||
bindAction('#createVariety', () => microBenchmark('injectAvg', iterations, createVariety));
|
||||
bindAction('#createVarietyResolved',
|
||||
() => microBenchmark('injectAvg', iterations, createVarietyResolved));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Injectable()
|
||||
class A {
|
||||
constructor() { count++; }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class B {
|
||||
constructor(a: A) { count++; }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class C {
|
||||
constructor(b: B) { count++; }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class D {
|
||||
constructor(c: C, b: B) { count++; }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class E {
|
||||
constructor(d: D, c: C) { count++; }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class F {
|
||||
constructor(e: E, d: D) { count++; }
|
||||
}
|
123
modules/benchmarks/src/old/largetable/largetable_benchmark.html
Normal file
123
modules/benchmarks/src/old/largetable/largetable_benchmark.html
Normal file
@ -0,0 +1,123 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="data:;base64,=">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
|
||||
<div>
|
||||
<form>
|
||||
<div>
|
||||
Use Viewcache:
|
||||
<label>
|
||||
Yes<input type="radio" name="viewcache" placeholder="use viewcache" value="true" checked="checked">
|
||||
</label>
|
||||
<label>
|
||||
No<input type="radio" name="viewcache" placeholder="use viewcache" value="false">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
rows:
|
||||
<input type="number" name="rows" value="100">
|
||||
columns:
|
||||
<input type="number" name="columns" value="20">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
baseline (to be used in conjuction with Baseline:createDom & Baseline:destroyDom buttons):
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="baseline"
|
||||
id="baseline">
|
||||
</div>
|
||||
<div>
|
||||
ngBind (not implemented):
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="ngBind"
|
||||
id="ngBind">
|
||||
</div>
|
||||
<div>
|
||||
ngBindOnce (not implemented):
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="ngBindOnce"
|
||||
id="ngBindOnce">
|
||||
</div>
|
||||
<div>
|
||||
interpolation:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="interpolation"
|
||||
id="interpolation"
|
||||
checked>
|
||||
</div>
|
||||
<div>
|
||||
attribute interpolation:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="interpolationAttr"
|
||||
id="interpolationAttr">
|
||||
</div>
|
||||
<div>
|
||||
ngBind + fnInvocation (not implemented):
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="ngBindFn"
|
||||
id="ngBindFn">
|
||||
</div>
|
||||
<div>
|
||||
interpolation + fnInvocation:
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="interpolationFn"
|
||||
id="interpolationFn">
|
||||
</div>
|
||||
<div>
|
||||
ngBind + filter (not implemented):
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="ngBindFilter"
|
||||
id="ngBindFilter">
|
||||
</div>
|
||||
<div>
|
||||
interpolation + filter (not implemented):
|
||||
<input type="radio"
|
||||
name="benchmarkType"
|
||||
value="interpolationFilter"
|
||||
id="interpolationFilter">
|
||||
</div>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h2>Angular2 largetable benchmark</h2>
|
||||
<p>
|
||||
<button id="ng2DestroyDom">destroyDom</button>
|
||||
<button id="ng2CreateDom">createDom</button>
|
||||
<button id="ng2UpdateDomProfile">profile updateDom</button>
|
||||
<button id="ng2CreateDomProfile">profile createDom</button>
|
||||
</p>
|
||||
|
||||
<h2>Baseline largetable benchmark</h2>
|
||||
<p>
|
||||
<button id="baselineDestroyDom">destroyDom</button>
|
||||
<button id="baselineCreateDom">createDom</button>
|
||||
<button id="baselineUpdateDomProfile">profile updateDom</button>
|
||||
<button id="baselineCreateDomProfile">profile createDom</button>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<app></app>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<baseline></baseline>
|
||||
</div>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
267
modules/benchmarks/src/old/largetable/largetable_benchmark.ts
Normal file
267
modules/benchmarks/src/old/largetable/largetable_benchmark.ts
Normal file
@ -0,0 +1,267 @@
|
||||
import {DOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {window, document, gc} from '@angular/facade/src/browser';
|
||||
import {
|
||||
getIntParameter,
|
||||
getStringParameter,
|
||||
bindAction,
|
||||
windowProfile,
|
||||
windowProfileEnd
|
||||
} from '@angular/testing/src/benchmark_util';
|
||||
import {bootstrap} from '@angular/platform-browser';
|
||||
import {Component} from '@angular/core';
|
||||
import {NgFor, NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common';
|
||||
import {ApplicationRef} from '@angular/core/src/application_ref';
|
||||
import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter';
|
||||
|
||||
import {ListWrapper} from '@angular/facade/src/collection';
|
||||
|
||||
import {Inject} from '@angular/core/src/di/decorators';
|
||||
import {reflector} from '@angular/core/src/reflection/reflection';
|
||||
|
||||
export const BENCHMARK_TYPE = 'LargetableComponent.benchmarkType';
|
||||
export const LARGETABLE_ROWS = 'LargetableComponent.rows';
|
||||
export const LARGETABLE_COLS = 'LargetableComponent.cols';
|
||||
|
||||
function _createBindings() {
|
||||
return [
|
||||
{provide: BENCHMARK_TYPE, useValue: getStringParameter('benchmarkType')},
|
||||
{provide: LARGETABLE_ROWS, useValue: getIntParameter('rows')},
|
||||
{provide: LARGETABLE_COLS, useValue: getIntParameter('columns')},
|
||||
];
|
||||
}
|
||||
|
||||
var BASELINE_LARGETABLE_TEMPLATE;
|
||||
|
||||
function setupReflector() {
|
||||
// TODO(kegluneq): Generate these.
|
||||
reflector.registerGetters({
|
||||
'benchmarktype': (o) => o.benchmarktype,
|
||||
'switch': (o) => null,
|
||||
'switchCase': (o) => o.switchCase
|
||||
});
|
||||
reflector.registerSetters({
|
||||
'benchmarktype': (o, v) => o.benchmarktype = v,
|
||||
'switch': (o, v) => null,
|
||||
'switchCase': (o, v) => o.switchCase = v
|
||||
});
|
||||
}
|
||||
|
||||
export function main() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
var totalRows = getIntParameter('rows');
|
||||
var totalColumns = getIntParameter('columns');
|
||||
BASELINE_LARGETABLE_TEMPLATE = DOM.createTemplate('<table></table>');
|
||||
|
||||
var app;
|
||||
var appRef;
|
||||
var baselineRootLargetableComponent;
|
||||
|
||||
function ng2DestroyDom() {
|
||||
// TODO: We need an initial value as otherwise the getter for data.value will fail
|
||||
// --> this should be already caught in change detection!
|
||||
app.data = null;
|
||||
app.benchmarkType = 'none';
|
||||
appRef.tick();
|
||||
}
|
||||
|
||||
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 ng2CreateDom() {
|
||||
var data = ListWrapper.createFixedSize(totalRows);
|
||||
|
||||
for (var i = 0; i < totalRows; i++) {
|
||||
data[i] = ListWrapper.createFixedSize(totalColumns);
|
||||
for (var j = 0; j < totalColumns; j++) {
|
||||
data[i][j] = new CellData(i, j);
|
||||
}
|
||||
}
|
||||
app.data = data;
|
||||
app.benchmarkType = getStringParameter('benchmarkType');
|
||||
appRef.tick();
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
|
||||
function initNg2() {
|
||||
bootstrap(AppComponent, _createBindings())
|
||||
.then((ref) => {
|
||||
var injector = ref.injector;
|
||||
app = ref.instance;
|
||||
appRef = injector.get(ApplicationRef);
|
||||
bindAction('#ng2DestroyDom', ng2DestroyDom);
|
||||
bindAction('#ng2CreateDom', ng2CreateDom);
|
||||
bindAction('#ng2UpdateDomProfile', profile(ng2CreateDom, noop, 'ng2-update'));
|
||||
bindAction('#ng2CreateDomProfile', profile(ng2CreateDom, ng2DestroyDom, 'ng2-create'));
|
||||
});
|
||||
setupReflector();
|
||||
}
|
||||
|
||||
function baselineDestroyDom() { baselineRootLargetableComponent.update(buildTable(0, 0)); }
|
||||
|
||||
function baselineCreateDom() {
|
||||
baselineRootLargetableComponent.update(buildTable(totalRows, totalColumns));
|
||||
}
|
||||
|
||||
function initBaseline() {
|
||||
baselineRootLargetableComponent = new BaseLineLargetableComponent(
|
||||
DOM.querySelector(document, 'baseline'), getStringParameter('benchmarkType'),
|
||||
getIntParameter('rows'), getIntParameter('columns'));
|
||||
|
||||
bindAction('#baselineDestroyDom', baselineDestroyDom);
|
||||
bindAction('#baselineCreateDom', baselineCreateDom);
|
||||
|
||||
bindAction('#baselineUpdateDomProfile', profile(baselineCreateDom, noop, 'baseline-update'));
|
||||
bindAction('#baselineCreateDomProfile',
|
||||
profile(baselineCreateDom, baselineDestroyDom, 'baseline-create'));
|
||||
}
|
||||
|
||||
initNg2();
|
||||
initBaseline();
|
||||
}
|
||||
|
||||
function buildTable(rows, columns) {
|
||||
var tbody = DOM.createElement('tbody');
|
||||
var template = DOM.createElement('span');
|
||||
var i, j, row, cell;
|
||||
DOM.appendChild(template, DOM.createElement('span'));
|
||||
DOM.appendChild(template, DOM.createTextNode(':'));
|
||||
DOM.appendChild(template, DOM.createElement('span'));
|
||||
DOM.appendChild(template, DOM.createTextNode('|'));
|
||||
|
||||
for (i = 0; i < rows; i++) {
|
||||
row = DOM.createElement('div');
|
||||
DOM.appendChild(tbody, row);
|
||||
for (j = 0; j < columns; j++) {
|
||||
cell = DOM.clone(template);
|
||||
DOM.appendChild(row, cell);
|
||||
DOM.setText(cell.childNodes[0], i.toString());
|
||||
DOM.setText(cell.childNodes[2], j.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return tbody;
|
||||
}
|
||||
|
||||
class BaseLineLargetableComponent {
|
||||
element;
|
||||
table;
|
||||
benchmarkType: string;
|
||||
rows: number;
|
||||
columns: number;
|
||||
constructor(element, benchmarkType, rows: number, columns: number) {
|
||||
this.element = element;
|
||||
this.benchmarkType = benchmarkType;
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
this.table = DOM.clone(BASELINE_LARGETABLE_TEMPLATE.content.firstChild);
|
||||
var shadowRoot = DOM.createShadowRoot(this.element);
|
||||
DOM.appendChild(shadowRoot, this.table);
|
||||
}
|
||||
update(tbody) {
|
||||
var oldBody = DOM.querySelector(this.table, 'tbody');
|
||||
if (oldBody != null) {
|
||||
DOM.replaceChild(this.table, tbody, oldBody);
|
||||
} else {
|
||||
DOM.appendChild(this.table, tbody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CellData {
|
||||
i: number;
|
||||
j: number;
|
||||
constructor(i, j) {
|
||||
this.i = i;
|
||||
this.j = j;
|
||||
}
|
||||
|
||||
jFn() { return this.j; }
|
||||
|
||||
iFn() { return this.i; }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'largetable',
|
||||
inputs: ['data', 'benchmarkType'],
|
||||
directives: [NgFor, NgSwitch, NgSwitchCase, NgSwitchDefault],
|
||||
template: `
|
||||
<table [ngSwitch]="benchmarkType">
|
||||
<tbody template="ngSwitchCase 'interpolation'">
|
||||
<tr template="ngFor let row of data">
|
||||
<td template="ngFor let column of row">
|
||||
{{column.i}}:{{column.j}}|
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody template="ngSwitchCase 'interpolationAttr'">
|
||||
<tr template="ngFor let row of data">
|
||||
<td template="ngFor let column of row" attr.i="{{column.i}}" attr.j="{{column.j}}">
|
||||
i,j attrs
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody template="ngSwitchCase 'interpolationFn'">
|
||||
<tr template="ngFor let row of data">
|
||||
<td template="ngFor let column of row">
|
||||
{{column.iFn()}}:{{column.jFn()}}|
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody template="ngSwitchDefault">
|
||||
<tr>
|
||||
<td>
|
||||
<em>{{benchmarkType}} not yet implemented</em>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>`
|
||||
})
|
||||
class LargetableComponent {
|
||||
data;
|
||||
benchmarkType: string;
|
||||
rows: number;
|
||||
columns: number;
|
||||
constructor(@Inject(BENCHMARK_TYPE) benchmarkType, @Inject(LARGETABLE_ROWS) rows,
|
||||
@Inject(LARGETABLE_COLS) columns) {
|
||||
this.benchmarkType = benchmarkType;
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
directives: [LargetableComponent],
|
||||
template: `<largetable [data]='data' [benchmarkType]='benchmarkType'></largetable>`
|
||||
})
|
||||
class AppComponent {
|
||||
data;
|
||||
benchmarkType: string;
|
||||
}
|
86
modules/benchmarks/src/old/naive_infinite_scroll/app.ts
Normal file
86
modules/benchmarks/src/old/naive_infinite_scroll/app.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import {isPresent} from '@angular/facade/src/lang';
|
||||
import {getIntParameter, bindAction} from '@angular/testing/src/benchmark_util';
|
||||
import {TimerWrapper} from '@angular/facade/src/async';
|
||||
import {ScrollAreaComponent} from './scroll_area';
|
||||
import {NgIf, NgFor} from '@angular/common';
|
||||
import {DOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {document} from '@angular/facade/src/browser';
|
||||
|
||||
import {Component, Directive} from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'scroll-app',
|
||||
directives: [ScrollAreaComponent, NgIf, NgFor],
|
||||
template: `
|
||||
<div>
|
||||
<div style="display: flex">
|
||||
<scroll-area id="testArea"></scroll-area>
|
||||
</div>
|
||||
<div template="ngIf scrollAreas.length > 0">
|
||||
<p>Following tables are only here to add weight to the UI:</p>
|
||||
<scroll-area template="ngFor let scrollArea of scrollAreas"></scroll-area>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
export class App {
|
||||
scrollAreas: number[];
|
||||
iterationCount: number;
|
||||
scrollIncrement: number;
|
||||
|
||||
constructor() {
|
||||
var appSize = getIntParameter('appSize');
|
||||
this.iterationCount = getIntParameter('iterationCount');
|
||||
this.scrollIncrement = getIntParameter('scrollIncrement');
|
||||
appSize = appSize > 1 ? appSize - 1 : 0; // draw at least one table
|
||||
this.scrollAreas = [];
|
||||
for (var i = 0; i < appSize; i++) {
|
||||
this.scrollAreas.push(i);
|
||||
}
|
||||
bindAction('#run-btn', () => { this.runBenchmark(); });
|
||||
bindAction('#reset-btn', () => {
|
||||
this._getScrollDiv().scrollTop = 0;
|
||||
var existingMarker = this._locateFinishedMarker();
|
||||
if (isPresent(existingMarker)) {
|
||||
DOM.removeChild(document.body, existingMarker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
runBenchmark() {
|
||||
var scrollDiv = this._getScrollDiv();
|
||||
var n: number = this.iterationCount;
|
||||
var scheduleScroll;
|
||||
scheduleScroll = () => {
|
||||
TimerWrapper.setTimeout(() => {
|
||||
scrollDiv.scrollTop += this.scrollIncrement;
|
||||
n--;
|
||||
if (n > 0) {
|
||||
scheduleScroll();
|
||||
} else {
|
||||
this._scheduleFinishedMarker();
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
scheduleScroll();
|
||||
}
|
||||
|
||||
// Puts a marker indicating that the test is finished.
|
||||
_scheduleFinishedMarker() {
|
||||
var existingMarker = this._locateFinishedMarker();
|
||||
if (isPresent(existingMarker)) {
|
||||
// Nothing to do, the marker is already there
|
||||
return;
|
||||
}
|
||||
TimerWrapper.setTimeout(() => {
|
||||
var finishedDiv = DOM.createElement('div');
|
||||
finishedDiv.id = 'done';
|
||||
DOM.setInnerHTML(finishedDiv, 'Finished');
|
||||
DOM.appendChild(document.body, finishedDiv);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
_locateFinishedMarker() { return DOM.querySelector(document.body, '#done'); }
|
||||
|
||||
_getScrollDiv() { return DOM.query('body /deep/ #scrollDiv'); }
|
||||
}
|
129
modules/benchmarks/src/old/naive_infinite_scroll/cells.ts
Normal file
129
modules/benchmarks/src/old/naive_infinite_scroll/cells.ts
Normal file
@ -0,0 +1,129 @@
|
||||
import {ListWrapper, Map} from '@angular/facade/src/collection';
|
||||
import {Company, Opportunity, Offering, Account, CustomDate, STATUS_LIST} from './common';
|
||||
import {NgFor} from '@angular/common';
|
||||
|
||||
import {Component, Directive} from '@angular/core';
|
||||
|
||||
export class HasStyle {
|
||||
cellWidth: number;
|
||||
|
||||
constructor() {}
|
||||
|
||||
set width(w: number) { this.cellWidth = w; }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'company-name',
|
||||
inputs: ['width: cell-width', 'company'],
|
||||
directives: [],
|
||||
template: `<div [style.width.px]="cellWidth">{{company.name}}</div>`
|
||||
})
|
||||
export class CompanyNameComponent extends HasStyle {
|
||||
company: Company;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'opportunity-name',
|
||||
inputs: ['width: cell-width', 'opportunity'],
|
||||
directives: [],
|
||||
template: `<div [style.width.px]="cellWidth">{{opportunity.name}}</div>`
|
||||
})
|
||||
export class OpportunityNameComponent extends HasStyle {
|
||||
opportunity: Opportunity;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'offering-name',
|
||||
inputs: ['width: cell-width', 'offering'],
|
||||
directives: [],
|
||||
template: `<div [style.width.px]="cellWidth">{{offering.name}}</div>`
|
||||
})
|
||||
export class OfferingNameComponent extends HasStyle {
|
||||
offering: Offering;
|
||||
}
|
||||
|
||||
export class Stage {
|
||||
name: string;
|
||||
isDisabled: boolean;
|
||||
backgroundColor: string;
|
||||
apply: Function;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'stage-buttons',
|
||||
inputs: ['width: cell-width', 'offering'],
|
||||
directives: [NgFor],
|
||||
template: `
|
||||
<div [style.width.px]="cellWidth">
|
||||
<button template="ngFor let stage of stages"
|
||||
[disabled]="stage.isDisabled"
|
||||
[style.background-color]="stage.backgroundColor"
|
||||
on-click="setStage(stage)">
|
||||
{{stage.name}}
|
||||
</button>
|
||||
</div>`
|
||||
})
|
||||
export class StageButtonsComponent extends HasStyle {
|
||||
_offering: Offering;
|
||||
stages: Stage[];
|
||||
|
||||
get offering(): Offering { return this._offering; }
|
||||
|
||||
set offering(offering: Offering) {
|
||||
this._offering = offering;
|
||||
this._computeStageButtons();
|
||||
}
|
||||
|
||||
setStage(stage: Stage) {
|
||||
this._offering.status = stage.name;
|
||||
this._computeStageButtons();
|
||||
}
|
||||
|
||||
_computeStageButtons() {
|
||||
var disabled = true;
|
||||
this.stages = ListWrapper.clone(STATUS_LIST.map((status) => {
|
||||
var isCurrent = this._offering.status == status;
|
||||
var stage = new Stage();
|
||||
stage.name = status;
|
||||
stage.isDisabled = disabled;
|
||||
stage.backgroundColor = disabled ? '#DDD' : isCurrent ? '#DDF' : '#FDD';
|
||||
if (isCurrent) {
|
||||
disabled = false;
|
||||
}
|
||||
return stage;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'account-cell',
|
||||
inputs: ['width: cell-width', 'account'],
|
||||
directives: [],
|
||||
template: `
|
||||
<div [style.width.px]="cellWidth">
|
||||
<a href="/account/{{account.accountId}}">
|
||||
{{account.accountId}}
|
||||
</a>
|
||||
</div>`
|
||||
})
|
||||
export class AccountCellComponent extends HasStyle {
|
||||
account: Account;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'formatted-cell',
|
||||
inputs: ['width: cell-width', 'value'],
|
||||
directives: [],
|
||||
template: `<div [style.width.px]="cellWidth">{{formattedValue}}</div>`
|
||||
})
|
||||
export class FormattedCellComponent extends HasStyle {
|
||||
formattedValue: string;
|
||||
|
||||
set value(value) {
|
||||
if (value instanceof CustomDate) {
|
||||
this.formattedValue = `${value.month}/${value.day}/${value.year}`;
|
||||
} else {
|
||||
this.formattedValue = value.toString();
|
||||
}
|
||||
}
|
||||
}
|
159
modules/benchmarks/src/old/naive_infinite_scroll/common.ts
Normal file
159
modules/benchmarks/src/old/naive_infinite_scroll/common.ts
Normal file
@ -0,0 +1,159 @@
|
||||
import {Math} from '@angular/facade/src/math';
|
||||
import {StringWrapper} from '@angular/facade/src/lang';
|
||||
import {ListWrapper, Map, MapWrapper} from '@angular/facade/src/collection';
|
||||
|
||||
export var ITEMS = 1000;
|
||||
export var ITEM_HEIGHT = 40;
|
||||
export var VISIBLE_ITEMS = 17;
|
||||
|
||||
export var HEIGHT = ITEMS * ITEM_HEIGHT;
|
||||
export var VIEW_PORT_HEIGHT = ITEM_HEIGHT * VISIBLE_ITEMS;
|
||||
|
||||
export var COMPANY_NAME_WIDTH = 100;
|
||||
export var OPPORTUNITY_NAME_WIDTH = 100;
|
||||
export var OFFERING_NAME_WIDTH = 100;
|
||||
export var ACCOUNT_CELL_WIDTH = 50;
|
||||
export var BASE_POINTS_WIDTH = 50;
|
||||
export var KICKER_POINTS_WIDTH = 50;
|
||||
export var STAGE_BUTTONS_WIDTH = 220;
|
||||
export var BUNDLES_WIDTH = 120;
|
||||
export var DUE_DATE_WIDTH = 100;
|
||||
export var END_DATE_WIDTH = 100;
|
||||
export var AAT_STATUS_WIDTH = 100;
|
||||
export var ROW_WIDTH = COMPANY_NAME_WIDTH + OPPORTUNITY_NAME_WIDTH + OFFERING_NAME_WIDTH +
|
||||
ACCOUNT_CELL_WIDTH + BASE_POINTS_WIDTH + KICKER_POINTS_WIDTH +
|
||||
STAGE_BUTTONS_WIDTH + BUNDLES_WIDTH + DUE_DATE_WIDTH + END_DATE_WIDTH +
|
||||
AAT_STATUS_WIDTH;
|
||||
|
||||
export var STATUS_LIST = ['Planned', 'Pitched', 'Won', 'Lost'];
|
||||
|
||||
export var AAT_STATUS_LIST = ['Active', 'Passive', 'Abandoned'];
|
||||
|
||||
// Imitate Streamy entities.
|
||||
|
||||
// Just a non-trivial object. Nothing fancy or correct.
|
||||
export class CustomDate {
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
|
||||
constructor(y: number, m: number, d: number) {
|
||||
this.year = y;
|
||||
this.month = m;
|
||||
this.day = d;
|
||||
}
|
||||
|
||||
addDays(days: number): CustomDate {
|
||||
var newDay = this.day + days;
|
||||
var newMonth = this.month + Math.floor(newDay / 30);
|
||||
newDay = newDay % 30;
|
||||
var newYear = this.year + Math.floor(newMonth / 12);
|
||||
return new CustomDate(newYear, newMonth, newDay);
|
||||
}
|
||||
|
||||
static now(): CustomDate { return new CustomDate(2014, 1, 28); }
|
||||
}
|
||||
|
||||
export class RawEntity {
|
||||
_data: Map<any, any>;
|
||||
|
||||
constructor() { this._data = new Map(); }
|
||||
|
||||
get(key: string) {
|
||||
if (key.indexOf('.') == -1) {
|
||||
return this._data[key];
|
||||
}
|
||||
var pieces = key.split('.');
|
||||
var last = ListWrapper.last(pieces);
|
||||
pieces.length = pieces.length - 1;
|
||||
var target = this._resolve(pieces, this);
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
return target[last];
|
||||
}
|
||||
|
||||
set(key: string, value) {
|
||||
if (key.indexOf('.') == -1) {
|
||||
this._data[key] = value;
|
||||
return;
|
||||
}
|
||||
var pieces = key.split('.');
|
||||
var last = ListWrapper.last(pieces);
|
||||
pieces.length = pieces.length - 1;
|
||||
var target = this._resolve(pieces, this);
|
||||
target[last] = value;
|
||||
}
|
||||
|
||||
remove(key: string) {
|
||||
if (!StringWrapper.contains(key, '.')) {
|
||||
return this._data.delete(key);
|
||||
}
|
||||
var pieces = key.split('.');
|
||||
var last = ListWrapper.last(pieces);
|
||||
pieces.length = pieces.length - 1;
|
||||
var target = this._resolve(pieces, this);
|
||||
return target.remove(last);
|
||||
}
|
||||
|
||||
_resolve(pieces, start) {
|
||||
var cur = start;
|
||||
for (var i = 0; i < pieces.length; i++) {
|
||||
cur = cur[pieces[i]];
|
||||
if (cur == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
|
||||
export class Company extends RawEntity {
|
||||
get name(): string { return this.get('name'); }
|
||||
set name(val: string) { this.set('name', val); }
|
||||
}
|
||||
|
||||
export class Offering extends RawEntity {
|
||||
get name(): string { return this.get('name'); }
|
||||
set name(val: string) { this.set('name', val); }
|
||||
|
||||
get company(): Company { return this.get('company'); }
|
||||
set company(val: Company) { this.set('company', val); }
|
||||
|
||||
get opportunity(): Opportunity { return this.get('opportunity'); }
|
||||
set opportunity(val: Opportunity) { this.set('opportunity', val); }
|
||||
|
||||
get account(): Account { return this.get('account'); }
|
||||
set account(val: Account) { this.set('account', val); }
|
||||
|
||||
get basePoints(): number { return this.get('basePoints'); }
|
||||
set basePoints(val: number) { this.set('basePoints', val); }
|
||||
|
||||
get kickerPoints(): number { return this.get('kickerPoints'); }
|
||||
set kickerPoints(val: number) { this.set('kickerPoints', val); }
|
||||
|
||||
get status(): string { return this.get('status'); }
|
||||
set status(val: string) { this.set('status', val); }
|
||||
|
||||
get bundles(): string { return this.get('bundles'); }
|
||||
set bundles(val: string) { this.set('bundles', val); }
|
||||
|
||||
get dueDate(): CustomDate { return this.get('dueDate'); }
|
||||
set dueDate(val: CustomDate) { this.set('dueDate', val); }
|
||||
|
||||
get endDate(): CustomDate { return this.get('endDate'); }
|
||||
set endDate(val: CustomDate) { this.set('endDate', val); }
|
||||
|
||||
get aatStatus(): string { return this.get('aatStatus'); }
|
||||
set aatStatus(val: string) { this.set('aatStatus', val); }
|
||||
}
|
||||
|
||||
export class Opportunity extends RawEntity {
|
||||
get name(): string { return this.get('name'); }
|
||||
set name(val: string) { this.set('name', val); }
|
||||
}
|
||||
|
||||
export class Account extends RawEntity {
|
||||
get accountId(): number { return this.get('accountId'); }
|
||||
set accountId(val: number) { this.set('accountId', val); }
|
||||
}
|
20
modules/benchmarks/src/old/naive_infinite_scroll/index.html
Normal file
20
modules/benchmarks/src/old/naive_infinite_scroll/index.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>AngularDart Scrolling Benchmark</title>
|
||||
</head>
|
||||
<body>
|
||||
<form>
|
||||
App size: <input type="text" name="appSize" value="1"><br>
|
||||
Iteration count: <input type="text" name="iterationCount" value="1"><br>
|
||||
Scroll increment: <input type="text" name="scrollIncrement" value="1"><br>
|
||||
</form>
|
||||
<div>
|
||||
<button id="run-btn">Run</button>
|
||||
<button id="reset-btn">Reset</button>
|
||||
</div>
|
||||
<scroll-app>Loading...</scroll-app>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
18
modules/benchmarks/src/old/naive_infinite_scroll/index.ts
Normal file
18
modules/benchmarks/src/old/naive_infinite_scroll/index.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {
|
||||
NgModule
|
||||
} from '@angular/core';
|
||||
|
||||
import {App} from './app';
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
bootstrap: [App]
|
||||
})
|
||||
class AppModule {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
import {StringWrapper} from '@angular/facade/src/lang';
|
||||
import {
|
||||
CustomDate,
|
||||
Offering,
|
||||
Company,
|
||||
Opportunity,
|
||||
Account,
|
||||
STATUS_LIST,
|
||||
AAT_STATUS_LIST
|
||||
} from './common';
|
||||
|
||||
export function generateOfferings(count: number): Offering[] {
|
||||
var res = [];
|
||||
for (var i = 0; i < count; i++) {
|
||||
res.push(generateOffering(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export function generateOffering(seed: number): Offering {
|
||||
var res = new Offering();
|
||||
res.name = generateName(seed++);
|
||||
res.company = generateCompany(seed++);
|
||||
res.opportunity = generateOpportunity(seed++);
|
||||
res.account = generateAccount(seed++);
|
||||
res.basePoints = seed % 10;
|
||||
res.kickerPoints = seed % 4;
|
||||
res.status = STATUS_LIST[seed % STATUS_LIST.length];
|
||||
res.bundles = randomString(seed++);
|
||||
res.dueDate = randomDate(seed++);
|
||||
res.endDate = randomDate(seed++, res.dueDate);
|
||||
res.aatStatus = AAT_STATUS_LIST[seed % AAT_STATUS_LIST.length];
|
||||
return res;
|
||||
}
|
||||
|
||||
export function generateCompany(seed: number): Company {
|
||||
var res = new Company();
|
||||
res.name = generateName(seed);
|
||||
return res;
|
||||
}
|
||||
|
||||
export function generateOpportunity(seed: number): Opportunity {
|
||||
var res = new Opportunity();
|
||||
res.name = generateName(seed);
|
||||
return res;
|
||||
}
|
||||
|
||||
export function generateAccount(seed: number): Account {
|
||||
var res = new Account();
|
||||
res.accountId = seed;
|
||||
return res;
|
||||
}
|
||||
|
||||
var names = [
|
||||
'Foo',
|
||||
'Bar',
|
||||
'Baz',
|
||||
'Qux',
|
||||
'Quux',
|
||||
'Garply',
|
||||
'Waldo',
|
||||
'Fred',
|
||||
'Plugh',
|
||||
'Xyzzy',
|
||||
'Thud',
|
||||
'Cruft',
|
||||
'Stuff'
|
||||
];
|
||||
|
||||
function generateName(seed: number): string {
|
||||
return names[seed % names.length];
|
||||
}
|
||||
|
||||
var offsets = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
function randomDate(seed: number, minDate: CustomDate = null): CustomDate {
|
||||
if (minDate == null) {
|
||||
minDate = CustomDate.now();
|
||||
}
|
||||
|
||||
return minDate.addDays(offsets[seed % offsets.length]);
|
||||
}
|
||||
|
||||
var stringLengths = [5, 7, 9, 11, 13];
|
||||
var charCodeOffsets = [0, 1, 2, 3, 4, 5, 6, 7, 8];
|
||||
|
||||
function randomString(seed: number): string {
|
||||
var len = stringLengths[seed % 5];
|
||||
var str = '';
|
||||
for (var i = 0; i < len; i++) {
|
||||
str += StringWrapper.fromCharCode(97 + charCodeOffsets[seed % 9] + i);
|
||||
}
|
||||
return str;
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
import {ListWrapper} from '@angular/facade/src/collection';
|
||||
import {Math} from '@angular/facade/src/math';
|
||||
|
||||
import {Component, Directive} from '@angular/core';
|
||||
|
||||
import {
|
||||
Offering,
|
||||
ITEMS,
|
||||
ITEM_HEIGHT,
|
||||
VISIBLE_ITEMS,
|
||||
VIEW_PORT_HEIGHT,
|
||||
ROW_WIDTH,
|
||||
HEIGHT
|
||||
} from './common';
|
||||
import {generateOfferings} from './random_data';
|
||||
import {ScrollItemComponent} from './scroll_item';
|
||||
import {NgFor} from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'scroll-area',
|
||||
directives: [ScrollItemComponent, NgFor],
|
||||
template: `
|
||||
<div>
|
||||
<div id="scrollDiv"
|
||||
[style.height.px]="viewPortHeight"
|
||||
style="width: 1000px; border: 1px solid #000; overflow: scroll"
|
||||
on-scroll="onScroll($event)">
|
||||
<div id="padding"></div>
|
||||
<div id="inner">
|
||||
<scroll-item
|
||||
template="ngFor let item of visibleItems"
|
||||
[offering]="item">
|
||||
</scroll-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
export class ScrollAreaComponent {
|
||||
_fullList: Offering[];
|
||||
visibleItems: Offering[];
|
||||
|
||||
viewPortHeight: number;
|
||||
paddingDiv;
|
||||
innerDiv;
|
||||
|
||||
constructor() {
|
||||
this._fullList = generateOfferings(ITEMS);
|
||||
this.visibleItems = [];
|
||||
this.viewPortHeight = VIEW_PORT_HEIGHT;
|
||||
this.onScroll(null);
|
||||
}
|
||||
|
||||
onScroll(evt) {
|
||||
var scrollTop = 0;
|
||||
if (evt != null) {
|
||||
var scrollDiv = evt.target;
|
||||
if (this.paddingDiv == null) {
|
||||
this.paddingDiv = scrollDiv.querySelector('#padding');
|
||||
}
|
||||
if (this.innerDiv == null) {
|
||||
this.innerDiv = scrollDiv.querySelector('#inner');
|
||||
this.innerDiv.style.setProperty('width', `${ROW_WIDTH}px`);
|
||||
}
|
||||
scrollTop = scrollDiv.scrollTop;
|
||||
}
|
||||
var iStart = Math.floor(scrollTop / ITEM_HEIGHT);
|
||||
var iEnd = Math.min(iStart + VISIBLE_ITEMS + 1, this._fullList.length);
|
||||
var padding = iStart * ITEM_HEIGHT;
|
||||
if (this.innerDiv != null) {
|
||||
this.innerDiv.style.setProperty('height', `${HEIGHT - padding}px`);
|
||||
}
|
||||
if (this.paddingDiv != null) {
|
||||
this.paddingDiv.style.setProperty('height', `${padding}px`);
|
||||
}
|
||||
this.visibleItems = ListWrapper.slice(this._fullList, iStart, iEnd);
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
import {
|
||||
CompanyNameComponent,
|
||||
OpportunityNameComponent,
|
||||
OfferingNameComponent,
|
||||
StageButtonsComponent,
|
||||
AccountCellComponent,
|
||||
FormattedCellComponent
|
||||
} from './cells';
|
||||
|
||||
import {Component, Directive} from '@angular/core';
|
||||
|
||||
import {
|
||||
Offering,
|
||||
ITEM_HEIGHT,
|
||||
COMPANY_NAME_WIDTH,
|
||||
OPPORTUNITY_NAME_WIDTH,
|
||||
OFFERING_NAME_WIDTH,
|
||||
ACCOUNT_CELL_WIDTH,
|
||||
BASE_POINTS_WIDTH,
|
||||
KICKER_POINTS_WIDTH,
|
||||
STAGE_BUTTONS_WIDTH,
|
||||
BUNDLES_WIDTH,
|
||||
DUE_DATE_WIDTH,
|
||||
END_DATE_WIDTH,
|
||||
AAT_STATUS_WIDTH
|
||||
} from './common';
|
||||
|
||||
@Component({
|
||||
selector: 'scroll-item',
|
||||
inputs: ['offering'],
|
||||
directives: [
|
||||
CompanyNameComponent,
|
||||
OpportunityNameComponent,
|
||||
OfferingNameComponent,
|
||||
StageButtonsComponent,
|
||||
AccountCellComponent,
|
||||
FormattedCellComponent
|
||||
],
|
||||
template: `
|
||||
<div class="row"
|
||||
[style.height.px]="itemHeight"
|
||||
[style.line-height.px]="itemHeight"
|
||||
style="font-size: 18px; display: flex; justify-content: space-between;">
|
||||
<company-name [company]="offering.company"
|
||||
[cell-width]="companyNameWidth">
|
||||
</company-name>
|
||||
<opportunity-name [opportunity]="offering.opportunity"
|
||||
[cell-width]="opportunityNameWidth">
|
||||
</opportunity-name>
|
||||
<offering-name [offering]="offering"
|
||||
[cell-width]="offeringNameWidth">
|
||||
</offering-name>
|
||||
<account-cell [account]="offering.account"
|
||||
[cell-width]="accountCellWidth">
|
||||
</account-cell>
|
||||
<formatted-cell [value]="offering.basePoints"
|
||||
[cell-width]="basePointsWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.kickerPoints"
|
||||
[cell-width]="kickerPointsWidth">
|
||||
</formatted-cell>
|
||||
<stage-buttons [offering]="offering"
|
||||
[cell-width]="stageButtonsWidth">
|
||||
</stage-buttons>
|
||||
<formatted-cell [value]="offering.bundles"
|
||||
[cell-width]="bundlesWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.dueDate"
|
||||
[cell-width]="dueDateWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.endDate"
|
||||
[cell-width]="endDateWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.aatStatus"
|
||||
[cell-width]="aatStatusWidth">
|
||||
</formatted-cell>
|
||||
</div>`
|
||||
})
|
||||
export class ScrollItemComponent {
|
||||
offering: Offering;
|
||||
|
||||
itemHeight: number;
|
||||
|
||||
constructor() { this.itemHeight = ITEM_HEIGHT; }
|
||||
|
||||
get companyNameWidth() { return COMPANY_NAME_WIDTH; }
|
||||
get opportunityNameWidth() { return OPPORTUNITY_NAME_WIDTH; }
|
||||
get offeringNameWidth() { return OFFERING_NAME_WIDTH; }
|
||||
get accountCellWidth() { return ACCOUNT_CELL_WIDTH; }
|
||||
get basePointsWidth() { return BASE_POINTS_WIDTH; }
|
||||
get kickerPointsWidth() { return KICKER_POINTS_WIDTH; }
|
||||
get stageButtonsWidth() { return STAGE_BUTTONS_WIDTH; }
|
||||
get bundlesWidth() { return BUNDLES_WIDTH; }
|
||||
get dueDateWidth() { return DUE_DATE_WIDTH; }
|
||||
get endDateWidth() { return END_DATE_WIDTH; }
|
||||
get aatStatusWidth() { return AAT_STATUS_WIDTH; }
|
||||
}
|
13
modules/benchmarks/src/old/page_load/page_load.html
Normal file
13
modules/benchmarks/src/old/page_load/page_load.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>Angular2 page load benchmark</h2>
|
||||
|
||||
<div>
|
||||
<app></app>
|
||||
</div>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
19
modules/benchmarks/src/old/page_load/page_load.ts
Normal file
19
modules/benchmarks/src/old/page_load/page_load.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import {Component, NgModule} from 'angular2/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
|
||||
@Component({selector: 'app', template: '<h1>Page Load Time</h1>'})
|
||||
class App {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
bootstrap: [App],
|
||||
})
|
||||
class AppModule {
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(App).then(() => {
|
||||
(<any>window).loadTime = Date.now() - performance.timing.navigationStart;
|
||||
(<any>window).someConstant = 1234567890;
|
||||
});
|
45
modules/benchmarks/src/old/static_tree/tree_benchmark.html
Normal file
45
modules/benchmarks/src/old/static_tree/tree_benchmark.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<h2>Params</h2>
|
||||
<form>
|
||||
<br>
|
||||
Use Viewcache:
|
||||
<label>
|
||||
Yes<input type="radio" name="viewcache" placeholder="use viewcache" value="true" checked="checked">
|
||||
</label>
|
||||
<label>
|
||||
No<input type="radio" name="viewcache" placeholder="use viewcache" value="false">
|
||||
</label>
|
||||
<br>
|
||||
<button>Apply</button>
|
||||
</form>
|
||||
|
||||
<h2>Angular2 static tree benchmark (depth 10)</h2>
|
||||
<p>
|
||||
<button id="ng2DestroyDom">destroyDom</button>
|
||||
<button id="ng2CreateDom">createDom</button>
|
||||
<button id="ng2UpdateDomProfile">profile updateDom</button>
|
||||
<button id="ng2CreateDomProfile">profile createDom</button>
|
||||
</p>
|
||||
|
||||
<h2>Baseline static tree benchmark (depth 10)</h2>
|
||||
<p>
|
||||
<button id="baselineDestroyDom">destroyDom</button>
|
||||
<button id="baselineCreateDom">createDom</button>
|
||||
<button id="baselineUpdateDomProfile">profile updateDom</button>
|
||||
<button id="baselineCreateDomProfile">profile createDom</button>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<app></app>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<baseline></baseline>
|
||||
</div>
|
||||
|
||||
$SCRIPTS$
|
||||
</body>
|
||||
</html>
|
321
modules/benchmarks/src/old/static_tree/tree_benchmark.ts
Normal file
321
modules/benchmarks/src/old/static_tree/tree_benchmark.ts
Normal file
@ -0,0 +1,321 @@
|
||||
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 {DOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {window, document, gc} from '@angular/facade/src/browser';
|
||||
import {
|
||||
getIntParameter,
|
||||
getStringParameter,
|
||||
bindAction,
|
||||
windowProfile,
|
||||
windowProfileEnd
|
||||
} from '@angular/testing/src/benchmark_util';
|
||||
import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
|
||||
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('<span>_<tree></tree><tree></tree></span>');
|
||||
}
|
||||
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: '<span>{{data.value}} </span>'})
|
||||
class StaticTreeComponent0 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent0],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent1 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent1],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent2 extends StaticTreeComponentBase {
|
||||
data: TreeNode;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent2],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent3 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent3],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent4 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent4],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent5 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent5],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent6 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent6],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent7 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent7],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent8 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'tree',
|
||||
inputs: ['data'],
|
||||
directives: [StaticTreeComponent8],
|
||||
template: `<span> {{data.value}} <tree [data]='data.right'></tree><tree [data]='data.left'></tree></span>`
|
||||
})
|
||||
class StaticTreeComponent9 extends StaticTreeComponentBase {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
directives: [StaticTreeComponent9, NgIf],
|
||||
template: `<tree *ngIf="initData != null" [data]='initData'></tree>`
|
||||
})
|
||||
class AppComponentWithStaticTree {
|
||||
initData: TreeNode;
|
||||
}
|
Reference in New Issue
Block a user