perf: add large table and deep tree benchmarks for render3 (#20855)
PR Close #20855
This commit is contained in:
parent
93b00cceb6
commit
0867e85163
|
@ -56,6 +56,15 @@ describe('largetable benchmark perf', () => {
|
||||||
}).then(done, done.fail);
|
}).then(done, done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should run for render3', (done) => {
|
||||||
|
runTableBenchmark({
|
||||||
|
id: `largeTable.render3.${worker.id}`,
|
||||||
|
url: 'all/benchmarks/src/largetable/render3/index.html',
|
||||||
|
ignoreBrowserSynchronization: true,
|
||||||
|
worker: worker
|
||||||
|
}).then(done, done.fail);
|
||||||
|
});
|
||||||
|
|
||||||
it('should run for the baseline', (done) => {
|
it('should run for the baseline', (done) => {
|
||||||
runTableBenchmark({
|
runTableBenchmark({
|
||||||
id: `largeTable.baseline.${worker.id}`,
|
id: `largeTable.baseline.${worker.id}`,
|
||||||
|
|
|
@ -25,6 +25,13 @@ describe('largetable benchmark spec', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should work for render3', () => {
|
||||||
|
testTableBenchmark({
|
||||||
|
url: 'all/benchmarks/src/largetable/render3/index.html',
|
||||||
|
ignoreBrowserSynchronization: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should work for the baseline', () => {
|
it('should work for the baseline', () => {
|
||||||
testTableBenchmark({
|
testTableBenchmark({
|
||||||
url: 'all/benchmarks/src/largetable/baseline/index.html',
|
url: 'all/benchmarks/src/largetable/baseline/index.html',
|
||||||
|
|
|
@ -49,6 +49,12 @@ export const Benchmarks: Benchmark[] = [
|
||||||
url: 'all/benchmarks/src/tree/ng2_switch/index.html',
|
url: 'all/benchmarks/src/tree/ng2_switch/index.html',
|
||||||
buttons: CreateDestroyButtons,
|
buttons: CreateDestroyButtons,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: `deepTree.ng2.render3`,
|
||||||
|
url: 'all/benchmarks/src/tree/render3/index.html',
|
||||||
|
buttons: CreateDestroyDetectChangesButtons,
|
||||||
|
ignoreBrowserSynchronization: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: `deepTree.baseline`,
|
id: `deepTree.baseline`,
|
||||||
url: 'all/benchmarks/src/tree/baseline/index.html',
|
url: 'all/benchmarks/src/tree/baseline/index.html',
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2>Params</h2>
|
||||||
|
<form>
|
||||||
|
Cols:
|
||||||
|
<input type="number" name="cols" placeholder="cols" value="40">
|
||||||
|
<br>
|
||||||
|
Rows:
|
||||||
|
<input type="number" name="rows" placeholder="rows" value="200">
|
||||||
|
<br>
|
||||||
|
<button>Apply</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h2>Render3 Largetable Benchmark</h2>
|
||||||
|
<p>
|
||||||
|
<button id="destroyDom">destroyDom</button>
|
||||||
|
<button id="createDom">createDom</button>
|
||||||
|
<button id="updateDomProfile">profile updateDom</button>
|
||||||
|
<button id="createDomProfile">profile createDom</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<largetable id="root"></largetable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
|
||||||
|
|| '../../bootstrap_ng2.js';
|
||||||
|
document.write('<script src="' + mainUrl + '">\u003c/script>');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* @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 {renderComponent} from '@angular/core/src/render3/index';
|
||||||
|
|
||||||
|
import {bindAction, profile} from '../../util';
|
||||||
|
|
||||||
|
import {LargeTableComponent, createDom, destroyDom} from './table';
|
||||||
|
|
||||||
|
function noop() {}
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
let component: LargeTableComponent;
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
component = renderComponent<LargeTableComponent>(LargeTableComponent, {renderer: document});
|
||||||
|
bindAction('#createDom', () => createDom(component));
|
||||||
|
bindAction('#destroyDom', () => destroyDom(component));
|
||||||
|
bindAction('#updateDomProfile', profile(() => createDom(component), noop, 'update'));
|
||||||
|
bindAction(
|
||||||
|
'#createDomProfile',
|
||||||
|
profile(() => createDom(component), () => destroyDom(component), 'create'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* @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 {C, E, T, V, a, b, b1, c, defineComponent, detectChanges, e, rC, rc, t, v} from '@angular/core/src/render3/index';
|
||||||
|
import {ComponentDef} from '@angular/core/src/render3/public_interfaces';
|
||||||
|
|
||||||
|
import {TableCell, buildTable, emptyTable} from '../util';
|
||||||
|
|
||||||
|
export class LargeTableComponent {
|
||||||
|
data: TableCell[][] = emptyTable;
|
||||||
|
|
||||||
|
/** @nocollapse */
|
||||||
|
static ngComponentDef: ComponentDef<LargeTableComponent> = defineComponent({
|
||||||
|
type: LargeTableComponent,
|
||||||
|
tag: 'largetable',
|
||||||
|
template: function(ctx: LargeTableComponent, cm: boolean) {
|
||||||
|
if (cm) {
|
||||||
|
E(0, 'table');
|
||||||
|
{
|
||||||
|
E(1, 'tbody');
|
||||||
|
{
|
||||||
|
C(2);
|
||||||
|
c();
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
rC(2);
|
||||||
|
{
|
||||||
|
for (let row of ctx.data) {
|
||||||
|
let cm1 = V(1);
|
||||||
|
{
|
||||||
|
if (cm1) {
|
||||||
|
E(0, 'tr');
|
||||||
|
C(1);
|
||||||
|
c();
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
rC(1);
|
||||||
|
{
|
||||||
|
for (let cell of row) {
|
||||||
|
let cm2 = V(2);
|
||||||
|
{
|
||||||
|
if (cm2) {
|
||||||
|
E(0, 'td');
|
||||||
|
{ T(1); }
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
a(0, 'style', b1('background-color:', cell.row % 2 ? '' : 'grey', ''));
|
||||||
|
t(1, b(cell.value));
|
||||||
|
}
|
||||||
|
v();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc();
|
||||||
|
}
|
||||||
|
v();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc();
|
||||||
|
},
|
||||||
|
factory: () => new LargeTableComponent(),
|
||||||
|
inputs: {data: 'data'}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function destroyDom(component: LargeTableComponent) {
|
||||||
|
component.data = emptyTable;
|
||||||
|
detectChanges(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createDom(component: LargeTableComponent) {
|
||||||
|
component.data = buildTable();
|
||||||
|
detectChanges(component);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2>Params</h2>
|
||||||
|
<form>
|
||||||
|
Depth:
|
||||||
|
<input type="number" name="depth" placeholder="depth" value="9">
|
||||||
|
<br>
|
||||||
|
<button>Apply</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h2>Render3 Tree Benchmark</h2>
|
||||||
|
<p>
|
||||||
|
<button id="destroyDom">destroyDom</button>
|
||||||
|
<button id="createDom">createDom</button>
|
||||||
|
<button id="detectChanges">detectChanges</button>
|
||||||
|
<button id="updateDomProfile">profile updateDom</button>
|
||||||
|
<button id="createDomProfile">profile createDom</button>
|
||||||
|
<button id="detectChangesProfile">profile detectChanges</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Change detection runs:<span id="numberOfChecks"></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<tree id="root"></tree>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
|
||||||
|
|| '../../bootstrap_ng2.js';
|
||||||
|
document.write('<script src="' + mainUrl + '">\u003c/script>');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* @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 {renderComponent} from '@angular/core/src/render3/index';
|
||||||
|
import {bindAction, profile} from '../../util';
|
||||||
|
import {TreeComponent, createDom, destroyDom, detectChanges} from './tree';
|
||||||
|
|
||||||
|
function noop() {}
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
let component: TreeComponent;
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
component = renderComponent(TreeComponent, {renderer: document});
|
||||||
|
bindAction('#createDom', () => createDom(component));
|
||||||
|
bindAction('#destroyDom', () => destroyDom(component));
|
||||||
|
bindAction('#detectChanges', () => detectChanges(component));
|
||||||
|
bindAction(
|
||||||
|
'#detectChangesProfile', profile(() => detectChanges(component), noop, 'detectChanges'));
|
||||||
|
bindAction('#updateDomProfile', profile(() => createDom(component), noop, 'update'));
|
||||||
|
bindAction(
|
||||||
|
'#createDomProfile',
|
||||||
|
profile(() => createDom(component), () => destroyDom(component), 'create'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
/**
|
||||||
|
* @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 {C, D, E, T, V, a, b, b1, c, defineComponent, detectChanges as _detectChanges, e, p, rC, rc, t, v} from '@angular/core/src/render3/index';
|
||||||
|
import {ComponentDef} from '@angular/core/src/render3/public_interfaces';
|
||||||
|
|
||||||
|
import {TreeNode, buildTree, emptyTree} from '../util';
|
||||||
|
|
||||||
|
export function destroyDom(component: TreeComponent) {
|
||||||
|
component.data = emptyTree;
|
||||||
|
_detectChanges(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createDom(component: TreeComponent) {
|
||||||
|
component.data = buildTree();
|
||||||
|
_detectChanges(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
const numberOfChecksEl = document.getElementById('numberOfChecks') !;
|
||||||
|
let detectChangesRuns = 0;
|
||||||
|
export function detectChanges(component: TreeComponent) {
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
_detectChanges(component);
|
||||||
|
}
|
||||||
|
detectChangesRuns += 10;
|
||||||
|
numberOfChecksEl.textContent = `${detectChangesRuns}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TreeComponent {
|
||||||
|
data: TreeNode = emptyTree;
|
||||||
|
|
||||||
|
/** @nocollapse */
|
||||||
|
static ngComponentDef: ComponentDef<TreeComponent> = defineComponent({
|
||||||
|
type: TreeComponent,
|
||||||
|
tag: 'tree',
|
||||||
|
template: function(ctx: TreeComponent, cm: boolean) {
|
||||||
|
if (cm) {
|
||||||
|
E(0, 'span');
|
||||||
|
{ T(1); }
|
||||||
|
e();
|
||||||
|
C(2);
|
||||||
|
c();
|
||||||
|
C(3);
|
||||||
|
c();
|
||||||
|
}
|
||||||
|
a(0, 'style', b1('background-color:', ctx.data.depth % 2 ? '' : 'grey', ''));
|
||||||
|
t(1, b1(' ', ctx.data.value, ' '));
|
||||||
|
rC(2);
|
||||||
|
{
|
||||||
|
if (ctx.data.left != null) {
|
||||||
|
let cm0 = V(0);
|
||||||
|
{
|
||||||
|
if (cm0) {
|
||||||
|
E(0, TreeComponent.ngComponentDef);
|
||||||
|
{ D(0, TreeComponent.ngComponentDef.n(), TreeComponent.ngComponentDef); }
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
p(0, 'data', b(ctx.data.left));
|
||||||
|
TreeComponent.ngComponentDef.r(0, 0);
|
||||||
|
}
|
||||||
|
v();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc();
|
||||||
|
rC(3);
|
||||||
|
{
|
||||||
|
if (ctx.data.right != null) {
|
||||||
|
let cm0 = V(0);
|
||||||
|
{
|
||||||
|
if (cm0) {
|
||||||
|
E(0, TreeComponent.ngComponentDef);
|
||||||
|
{ D(0, TreeComponent.ngComponentDef.n(), TreeComponent.ngComponentDef); }
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
p(0, 'data', b(ctx.data.right));
|
||||||
|
TreeComponent.ngComponentDef.r(0, 0);
|
||||||
|
}
|
||||||
|
v();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc();
|
||||||
|
},
|
||||||
|
factory: () => new TreeComponent,
|
||||||
|
inputs: {data: 'data'}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TreeFunction extends TreeComponent {
|
||||||
|
data: TreeNode = emptyTree;
|
||||||
|
|
||||||
|
/** @nocollapse */
|
||||||
|
static ngComponentDef: ComponentDef<TreeFunction> = defineComponent({
|
||||||
|
type: TreeFunction,
|
||||||
|
tag: 'tree',
|
||||||
|
template: function(ctx: TreeFunction, cm: boolean) {
|
||||||
|
// bit of a hack
|
||||||
|
TreeTpl(ctx.data, cm);
|
||||||
|
},
|
||||||
|
factory: () => new TreeFunction,
|
||||||
|
inputs: {data: 'data'}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TreeTpl(ctx: TreeNode, cm: boolean) {
|
||||||
|
if (cm) {
|
||||||
|
E(0, 'span');
|
||||||
|
{ T(1); }
|
||||||
|
e();
|
||||||
|
C(2);
|
||||||
|
c();
|
||||||
|
C(3);
|
||||||
|
c();
|
||||||
|
}
|
||||||
|
a(0, 'style', b1('background-color:', ctx.depth % 2 ? '' : 'grey', ''));
|
||||||
|
t(1, b1(' ', ctx.value, ' '));
|
||||||
|
rC(2);
|
||||||
|
{
|
||||||
|
if (ctx.left != null) {
|
||||||
|
let cm0 = V(0);
|
||||||
|
{ TreeTpl(ctx.left, cm0); }
|
||||||
|
v();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc();
|
||||||
|
rC(3);
|
||||||
|
{
|
||||||
|
if (ctx.right != null) {
|
||||||
|
let cm0 = V(0);
|
||||||
|
{ TreeTpl(ctx.right, cm0); }
|
||||||
|
v();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc();
|
||||||
|
}
|
Loading…
Reference in New Issue