Skip to content

Commit 0867e85

Browse files
marclavalIgorMinar
authored andcommitted
perf: add large table and deep tree benchmarks for render3 (#20855)
PR Close #20855
1 parent 93b00cc commit 0867e85

9 files changed

Lines changed: 369 additions & 0 deletions

File tree

modules/benchmarks/e2e_test/largetable_perf.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ describe('largetable benchmark perf', () => {
5656
}).then(done, done.fail);
5757
});
5858

59+
it('should run for render3', (done) => {
60+
runTableBenchmark({
61+
id: `largeTable.render3.${worker.id}`,
62+
url: 'all/benchmarks/src/largetable/render3/index.html',
63+
ignoreBrowserSynchronization: true,
64+
worker: worker
65+
}).then(done, done.fail);
66+
});
67+
5968
it('should run for the baseline', (done) => {
6069
runTableBenchmark({
6170
id: `largeTable.baseline.${worker.id}`,

modules/benchmarks/e2e_test/largetable_spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ describe('largetable benchmark spec', () => {
2525
});
2626
});
2727

28+
it('should work for render3', () => {
29+
testTableBenchmark({
30+
url: 'all/benchmarks/src/largetable/render3/index.html',
31+
ignoreBrowserSynchronization: true,
32+
});
33+
});
34+
2835
it('should work for the baseline', () => {
2936
testTableBenchmark({
3037
url: 'all/benchmarks/src/largetable/baseline/index.html',

modules/benchmarks/e2e_test/tree_data.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ export const Benchmarks: Benchmark[] = [
4949
url: 'all/benchmarks/src/tree/ng2_switch/index.html',
5050
buttons: CreateDestroyButtons,
5151
},
52+
{
53+
id: `deepTree.ng2.render3`,
54+
url: 'all/benchmarks/src/tree/render3/index.html',
55+
buttons: CreateDestroyDetectChangesButtons,
56+
ignoreBrowserSynchronization: true,
57+
},
5258
{
5359
id: `deepTree.baseline`,
5460
url: 'all/benchmarks/src/tree/baseline/index.html',
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!doctype html>
2+
<html>
3+
<body>
4+
5+
<h2>Params</h2>
6+
<form>
7+
Cols:
8+
<input type="number" name="cols" placeholder="cols" value="40">
9+
<br>
10+
Rows:
11+
<input type="number" name="rows" placeholder="rows" value="200">
12+
<br>
13+
<button>Apply</button>
14+
</form>
15+
16+
<h2>Render3 Largetable Benchmark</h2>
17+
<p>
18+
<button id="destroyDom">destroyDom</button>
19+
<button id="createDom">createDom</button>
20+
<button id="updateDomProfile">profile updateDom</button>
21+
<button id="createDomProfile">profile createDom</button>
22+
</p>
23+
24+
<div>
25+
<largetable id="root"></largetable>
26+
</div>
27+
28+
<script>
29+
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
30+
|| '../../bootstrap_ng2.js';
31+
document.write('<script src="' + mainUrl + '">\u003c/script>');
32+
</script>
33+
</body>
34+
</html>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {renderComponent} from '@angular/core/src/render3/index';
10+
11+
import {bindAction, profile} from '../../util';
12+
13+
import {LargeTableComponent, createDom, destroyDom} from './table';
14+
15+
function noop() {}
16+
17+
export function main() {
18+
let component: LargeTableComponent;
19+
if (typeof window !== 'undefined') {
20+
component = renderComponent<LargeTableComponent>(LargeTableComponent, {renderer: document});
21+
bindAction('#createDom', () => createDom(component));
22+
bindAction('#destroyDom', () => destroyDom(component));
23+
bindAction('#updateDomProfile', profile(() => createDom(component), noop, 'update'));
24+
bindAction(
25+
'#createDomProfile',
26+
profile(() => createDom(component), () => destroyDom(component), 'create'));
27+
}
28+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {C, E, T, V, a, b, b1, c, defineComponent, detectChanges, e, rC, rc, t, v} from '@angular/core/src/render3/index';
10+
import {ComponentDef} from '@angular/core/src/render3/public_interfaces';
11+
12+
import {TableCell, buildTable, emptyTable} from '../util';
13+
14+
export class LargeTableComponent {
15+
data: TableCell[][] = emptyTable;
16+
17+
/** @nocollapse */
18+
static ngComponentDef: ComponentDef<LargeTableComponent> = defineComponent({
19+
type: LargeTableComponent,
20+
tag: 'largetable',
21+
template: function(ctx: LargeTableComponent, cm: boolean) {
22+
if (cm) {
23+
E(0, 'table');
24+
{
25+
E(1, 'tbody');
26+
{
27+
C(2);
28+
c();
29+
}
30+
e();
31+
}
32+
e();
33+
}
34+
rC(2);
35+
{
36+
for (let row of ctx.data) {
37+
let cm1 = V(1);
38+
{
39+
if (cm1) {
40+
E(0, 'tr');
41+
C(1);
42+
c();
43+
e();
44+
}
45+
rC(1);
46+
{
47+
for (let cell of row) {
48+
let cm2 = V(2);
49+
{
50+
if (cm2) {
51+
E(0, 'td');
52+
{ T(1); }
53+
e();
54+
}
55+
a(0, 'style', b1('background-color:', cell.row % 2 ? '' : 'grey', ''));
56+
t(1, b(cell.value));
57+
}
58+
v();
59+
}
60+
}
61+
rc();
62+
}
63+
v();
64+
}
65+
}
66+
rc();
67+
},
68+
factory: () => new LargeTableComponent(),
69+
inputs: {data: 'data'}
70+
});
71+
}
72+
73+
export function destroyDom(component: LargeTableComponent) {
74+
component.data = emptyTable;
75+
detectChanges(component);
76+
}
77+
78+
export function createDom(component: LargeTableComponent) {
79+
component.data = buildTable();
80+
detectChanges(component);
81+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!doctype html>
2+
<html>
3+
<body>
4+
5+
<h2>Params</h2>
6+
<form>
7+
Depth:
8+
<input type="number" name="depth" placeholder="depth" value="9">
9+
<br>
10+
<button>Apply</button>
11+
</form>
12+
13+
<h2>Render3 Tree Benchmark</h2>
14+
<p>
15+
<button id="destroyDom">destroyDom</button>
16+
<button id="createDom">createDom</button>
17+
<button id="detectChanges">detectChanges</button>
18+
<button id="updateDomProfile">profile updateDom</button>
19+
<button id="createDomProfile">profile createDom</button>
20+
<button id="detectChangesProfile">profile detectChanges</button>
21+
</p>
22+
23+
<div>
24+
Change detection runs:<span id="numberOfChecks"></span>
25+
</div>
26+
<div>
27+
<tree id="root"></tree>
28+
</div>
29+
30+
<script>
31+
var mainUrl = window.location.search.split(/[?&]main=([^&]+)/)[1]
32+
|| '../../bootstrap_ng2.js';
33+
document.write('<script src="' + mainUrl + '">\u003c/script>');
34+
</script>
35+
</body>
36+
</html>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {renderComponent} from '@angular/core/src/render3/index';
10+
import {bindAction, profile} from '../../util';
11+
import {TreeComponent, createDom, destroyDom, detectChanges} from './tree';
12+
13+
function noop() {}
14+
15+
export function main() {
16+
let component: TreeComponent;
17+
if (typeof window !== 'undefined') {
18+
component = renderComponent(TreeComponent, {renderer: document});
19+
bindAction('#createDom', () => createDom(component));
20+
bindAction('#destroyDom', () => destroyDom(component));
21+
bindAction('#detectChanges', () => detectChanges(component));
22+
bindAction(
23+
'#detectChangesProfile', profile(() => detectChanges(component), noop, 'detectChanges'));
24+
bindAction('#updateDomProfile', profile(() => createDom(component), noop, 'update'));
25+
bindAction(
26+
'#createDomProfile',
27+
profile(() => createDom(component), () => destroyDom(component), 'create'));
28+
}
29+
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
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';
10+
import {ComponentDef} from '@angular/core/src/render3/public_interfaces';
11+
12+
import {TreeNode, buildTree, emptyTree} from '../util';
13+
14+
export function destroyDom(component: TreeComponent) {
15+
component.data = emptyTree;
16+
_detectChanges(component);
17+
}
18+
19+
export function createDom(component: TreeComponent) {
20+
component.data = buildTree();
21+
_detectChanges(component);
22+
}
23+
24+
const numberOfChecksEl = document.getElementById('numberOfChecks') !;
25+
let detectChangesRuns = 0;
26+
export function detectChanges(component: TreeComponent) {
27+
for (let i = 0; i < 10; i++) {
28+
_detectChanges(component);
29+
}
30+
detectChangesRuns += 10;
31+
numberOfChecksEl.textContent = `${detectChangesRuns}`;
32+
}
33+
34+
export class TreeComponent {
35+
data: TreeNode = emptyTree;
36+
37+
/** @nocollapse */
38+
static ngComponentDef: ComponentDef<TreeComponent> = defineComponent({
39+
type: TreeComponent,
40+
tag: 'tree',
41+
template: function(ctx: TreeComponent, cm: boolean) {
42+
if (cm) {
43+
E(0, 'span');
44+
{ T(1); }
45+
e();
46+
C(2);
47+
c();
48+
C(3);
49+
c();
50+
}
51+
a(0, 'style', b1('background-color:', ctx.data.depth % 2 ? '' : 'grey', ''));
52+
t(1, b1(' ', ctx.data.value, ' '));
53+
rC(2);
54+
{
55+
if (ctx.data.left != null) {
56+
let cm0 = V(0);
57+
{
58+
if (cm0) {
59+
E(0, TreeComponent.ngComponentDef);
60+
{ D(0, TreeComponent.ngComponentDef.n(), TreeComponent.ngComponentDef); }
61+
e();
62+
}
63+
p(0, 'data', b(ctx.data.left));
64+
TreeComponent.ngComponentDef.r(0, 0);
65+
}
66+
v();
67+
}
68+
}
69+
rc();
70+
rC(3);
71+
{
72+
if (ctx.data.right != null) {
73+
let cm0 = V(0);
74+
{
75+
if (cm0) {
76+
E(0, TreeComponent.ngComponentDef);
77+
{ D(0, TreeComponent.ngComponentDef.n(), TreeComponent.ngComponentDef); }
78+
e();
79+
}
80+
p(0, 'data', b(ctx.data.right));
81+
TreeComponent.ngComponentDef.r(0, 0);
82+
}
83+
v();
84+
}
85+
}
86+
rc();
87+
},
88+
factory: () => new TreeComponent,
89+
inputs: {data: 'data'}
90+
});
91+
}
92+
93+
export class TreeFunction extends TreeComponent {
94+
data: TreeNode = emptyTree;
95+
96+
/** @nocollapse */
97+
static ngComponentDef: ComponentDef<TreeFunction> = defineComponent({
98+
type: TreeFunction,
99+
tag: 'tree',
100+
template: function(ctx: TreeFunction, cm: boolean) {
101+
// bit of a hack
102+
TreeTpl(ctx.data, cm);
103+
},
104+
factory: () => new TreeFunction,
105+
inputs: {data: 'data'}
106+
});
107+
}
108+
109+
export function TreeTpl(ctx: TreeNode, cm: boolean) {
110+
if (cm) {
111+
E(0, 'span');
112+
{ T(1); }
113+
e();
114+
C(2);
115+
c();
116+
C(3);
117+
c();
118+
}
119+
a(0, 'style', b1('background-color:', ctx.depth % 2 ? '' : 'grey', ''));
120+
t(1, b1(' ', ctx.value, ' '));
121+
rC(2);
122+
{
123+
if (ctx.left != null) {
124+
let cm0 = V(0);
125+
{ TreeTpl(ctx.left, cm0); }
126+
v();
127+
}
128+
}
129+
rc();
130+
rC(3);
131+
{
132+
if (ctx.right != null) {
133+
let cm0 = V(0);
134+
{ TreeTpl(ctx.right, cm0); }
135+
v();
136+
}
137+
}
138+
rc();
139+
}

0 commit comments

Comments
 (0)