test(ivy): remove code duplication from node perf benchmarks (#32104)
PR Close #32104
This commit is contained in:
parent
be665d8de1
commit
33fab26930
@ -13,8 +13,16 @@ ts_library(
|
|||||||
)
|
)
|
||||||
|
|
||||||
ng_rollup_bundle(
|
ng_rollup_bundle(
|
||||||
name = "bundle",
|
name = "interpolation",
|
||||||
entry_point = ":index.ts",
|
entry_point = ":interpolation/index.ts",
|
||||||
|
deps = [
|
||||||
|
":perf_lib",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ng_rollup_bundle(
|
||||||
|
name = "noop_change_detection",
|
||||||
|
entry_point = ":noop_change_detection/index.ts",
|
||||||
deps = [
|
deps = [
|
||||||
":perf_lib",
|
":perf_lib",
|
||||||
],
|
],
|
11
packages/core/test/render3/perf/README.md
Normal file
11
packages/core/test/render3/perf/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
### Build
|
||||||
|
|
||||||
|
yarn bazel build //packages/core/test/render3/perf/{name}.min_debug.es2015.js --define=compile=aot
|
||||||
|
|
||||||
|
### Run
|
||||||
|
|
||||||
|
time node --no-turbo-inlining dist/bin/packages/core/test/render3/perf/{name}.min_debug.es2015.js
|
||||||
|
|
||||||
|
### Profile
|
||||||
|
|
||||||
|
node --no-turbo-inlining --inspect-brk dist/bin/packages/core/test/render3/perf/{name}.min_debug.es2015.js
|
@ -1,11 +0,0 @@
|
|||||||
### Build
|
|
||||||
|
|
||||||
yarn bazel build //packages/core/test/render3/perf/interpolation:bundle.min_debug.es2015.js --define=compile=aot
|
|
||||||
|
|
||||||
### Run
|
|
||||||
|
|
||||||
time node --no-turbo-inlining dist/bin/packages/core/test/render3/perf/interpolation/bundle.min_debug.es2015.js
|
|
||||||
|
|
||||||
### Profile
|
|
||||||
|
|
||||||
node --no-turbo-inlining --inspect-brk dist/bin/packages/core/test/render3/perf/interpolation/bundle.min_debug.es2015.js
|
|
@ -1,74 +1,13 @@
|
|||||||
import {ɵɵelementEnd, ɵɵelementStart} from '../../../../src/render3/instructions/element';
|
import {ɵɵelementEnd, ɵɵelementStart} from '../../../../src/render3/instructions/element';
|
||||||
import {ɵɵselect} from '../../../../src/render3/instructions/select';
|
import {ɵɵselect} from '../../../../src/render3/instructions/select';
|
||||||
import {addToViewTree, createLContainer, createLView, createTNode, createTView, getOrCreateTNode, refreshView, renderView} from '../../../../src/render3/instructions/shared';
|
import {refreshView} from '../../../../src/render3/instructions/shared';
|
||||||
import {ɵɵtext} from '../../../../src/render3/instructions/text';
|
import {ɵɵtext} from '../../../../src/render3/instructions/text';
|
||||||
import {ɵɵtextInterpolate} from '../../../../src/render3/instructions/text_interpolation';
|
import {ɵɵtextInterpolate} from '../../../../src/render3/instructions/text_interpolation';
|
||||||
import {RenderFlags} from '../../../../src/render3/interfaces/definition';
|
import {RenderFlags} from '../../../../src/render3/interfaces/definition';
|
||||||
import {TNodeType, TViewNode} from '../../../../src/render3/interfaces/node';
|
import {TVIEW} from '../../../../src/render3/interfaces/view';
|
||||||
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, RendererStyleFlags3} from '../../../../src/render3/interfaces/renderer';
|
import {setupRootViewWithEmbeddedViews} from '../setup';
|
||||||
import {LViewFlags, TView} from '../../../../src/render3/interfaces/view';
|
|
||||||
import {insertView} from '../../../../src/render3/node_manipulation';
|
|
||||||
|
|
||||||
class WebWorkerRenderNode implements RNode, RComment, RText {
|
`<div>
|
||||||
textContent: string|null = null;
|
|
||||||
parentNode: RNode|null = null;
|
|
||||||
parentElement: RElement|null = null;
|
|
||||||
nextSibling: RNode|null = null;
|
|
||||||
removeChild(oldChild: RNode): RNode { return oldChild; }
|
|
||||||
insertBefore(newChild: RNode, refChild: RNode|null, isViewRoot: boolean): void {}
|
|
||||||
appendChild(newChild: RNode): RNode { return newChild; }
|
|
||||||
}
|
|
||||||
|
|
||||||
class NoopRenderer implements ProceduralRenderer3 {
|
|
||||||
destroy(): void { throw new Error('Method not implemented.'); }
|
|
||||||
createComment(value: string): RComment { return new WebWorkerRenderNode(); }
|
|
||||||
createElement(name: string, namespace?: string|null|undefined): RElement {
|
|
||||||
return new WebWorkerRenderNode() as any as RElement;
|
|
||||||
}
|
|
||||||
createText(value: string): RText { return new WebWorkerRenderNode(); }
|
|
||||||
destroyNode?: ((node: RNode) => void)|null|undefined;
|
|
||||||
appendChild(parent: RElement, newChild: RNode): void {}
|
|
||||||
insertBefore(parent: RNode, newChild: RNode, refChild: RNode|null): void {}
|
|
||||||
removeChild(parent: RElement, oldChild: RNode, isHostElement?: boolean|undefined): void {}
|
|
||||||
selectRootElement(selectorOrNode: any): RElement { throw new Error('Method not implemented.'); }
|
|
||||||
parentNode(node: RNode): RElement|null { throw new Error('Method not implemented.'); }
|
|
||||||
nextSibling(node: RNode): RNode|null { throw new Error('Method not implemented.'); }
|
|
||||||
setAttribute(el: RElement, name: string, value: string, namespace?: string|null|undefined): void {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
removeAttribute(el: RElement, name: string, namespace?: string|null|undefined): void {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
addClass(el: RElement, name: string): void { throw new Error('Method not implemented.'); }
|
|
||||||
removeClass(el: RElement, name: string): void { throw new Error('Method not implemented.'); }
|
|
||||||
setStyle(el: RElement, style: string, value: any, flags?: RendererStyleFlags3|undefined): void {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
removeStyle(el: RElement, style: string, flags?: RendererStyleFlags3|undefined): void {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
setProperty(el: RElement, name: string, value: any): void {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
setValue(node: RComment|RText, value: string): void { node.textContent = value; }
|
|
||||||
listen(
|
|
||||||
target: RNode|'document'|'window'|'body', eventName: string,
|
|
||||||
callback: (event: any) => boolean | void): () => void {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NoopRendererFactory implements RendererFactory3 {
|
|
||||||
createRenderer(hostElement: RElement|null, rendererType: null): Renderer3 {
|
|
||||||
return new NoopRenderer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @Component({
|
|
||||||
selector: 'test',
|
|
||||||
template: `
|
|
||||||
<ng-template>
|
|
||||||
<div>
|
|
||||||
<button>{{'0'}}</button>
|
<button>{{'0'}}</button>
|
||||||
<button>{{'1'}}</button>
|
<button>{{'1'}}</button>
|
||||||
<button>{{'2'}}</button>
|
<button>{{'2'}}</button>
|
||||||
@ -80,13 +19,7 @@ class NoopRendererFactory implements RendererFactory3 {
|
|||||||
<button>{{'8'}}</button>
|
<button>{{'8'}}</button>
|
||||||
<button>{{'9'}}</button>
|
<button>{{'9'}}</button>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>`
|
</ng-template>`;
|
||||||
})
|
|
||||||
class TestComponent {
|
|
||||||
} */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function TestInterpolationComponent_ng_template_0_Template(rf: RenderFlags, ctx: any) {
|
function TestInterpolationComponent_ng_template_0_Template(rf: RenderFlags, ctx: any) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
ɵɵelementStart(0, 'div');
|
ɵɵelementStart(0, 'div');
|
||||||
@ -147,36 +80,9 @@ function TestInterpolationComponent_ng_template_0_Template(rf: RenderFlags, ctx:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const mockRNode = new WebWorkerRenderNode();
|
const rootLView =
|
||||||
|
setupRootViewWithEmbeddedViews(TestInterpolationComponent_ng_template_0_Template, 21, 10, 1000);
|
||||||
// Create a root view
|
const rootTView = rootLView[TVIEW];
|
||||||
const rootTView = createTView(-1, null, 1, 0, null, null, null, null);
|
|
||||||
const tContainerNode = getOrCreateTNode(rootTView, null, 0, TNodeType.Container, null, null);
|
|
||||||
const rootLView = createLView(
|
|
||||||
null, rootTView, {}, LViewFlags.CheckAlways | LViewFlags.IsRoot, null, null,
|
|
||||||
new NoopRendererFactory(), new NoopRenderer());
|
|
||||||
const lContainer =
|
|
||||||
createLContainer(mockRNode as RComment, rootLView, mockRNode as RComment, tContainerNode, true);
|
|
||||||
addToViewTree(rootLView, lContainer);
|
|
||||||
|
|
||||||
const embeddedTView = createTView(
|
|
||||||
-1, TestInterpolationComponent_ng_template_0_Template, 21, 10, null, null, null, null);
|
|
||||||
|
|
||||||
function createAndInsertEmbeddedView(tView: TView, index: number) {
|
|
||||||
const viewTNode = createTNode(rootTView, null, TNodeType.View, -1, null, null) as TViewNode;
|
|
||||||
const embeddedLView = createLView(
|
|
||||||
rootLView, tView, {}, LViewFlags.CheckAlways, null, viewTNode, new NoopRendererFactory(),
|
|
||||||
new NoopRenderer());
|
|
||||||
renderView(embeddedLView, embeddedTView, null);
|
|
||||||
insertView(embeddedLView, lContainer, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create embedded views and add them to the container
|
|
||||||
for (let i = 0; i < 1000; i++) {
|
|
||||||
createAndInsertEmbeddedView(embeddedTView, i);
|
|
||||||
}
|
|
||||||
// run in the creation mode to set flags etc.
|
|
||||||
renderView(rootLView, rootTView, null);
|
|
||||||
|
|
||||||
// run change detection in the update mode
|
// run change detection in the update mode
|
||||||
console.profile('update');
|
console.profile('update');
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:private"])
|
|
||||||
|
|
||||||
load("//tools:defaults.bzl", "ts_library", "ng_rollup_bundle")
|
|
||||||
|
|
||||||
ts_library(
|
|
||||||
name = "perf_lib",
|
|
||||||
srcs = glob(
|
|
||||||
["**/*.ts"],
|
|
||||||
),
|
|
||||||
deps = [
|
|
||||||
"//packages/core",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ng_rollup_bundle(
|
|
||||||
name = "bundle",
|
|
||||||
entry_point = ":index.ts",
|
|
||||||
deps = [
|
|
||||||
":perf_lib",
|
|
||||||
],
|
|
||||||
)
|
|
@ -1,44 +1,13 @@
|
|||||||
import {addToViewTree, createLContainer, createLView, createTView, getOrCreateTNode, refreshView, renderView} from '../../../../src/render3/instructions/shared';
|
import {refreshView} from '../../../../src/render3/instructions/shared';
|
||||||
import {TNodeType} from '../../../../src/render3/interfaces/node';
|
import {TVIEW} from '../../../../src/render3/interfaces/view';
|
||||||
import {RComment, Renderer3, RendererFactory3} from '../../../../src/render3/interfaces/renderer';
|
import {setupRootViewWithEmbeddedViews} from '../setup';
|
||||||
import {LViewFlags, TView} from '../../../../src/render3/interfaces/view';
|
|
||||||
import {insertView} from '../../../../src/render3/node_manipulation';
|
|
||||||
|
|
||||||
class WebWorkerRenderNode {}
|
const rootLView = setupRootViewWithEmbeddedViews(null, 0, 0, 1000);
|
||||||
|
const rootTView = rootLView[TVIEW];
|
||||||
const mockRNode = new WebWorkerRenderNode();
|
|
||||||
|
|
||||||
// Create a root view
|
|
||||||
const rootTView = createTView(-1, null, 1, 0, null, null, null, null);
|
|
||||||
const tContainerNode = getOrCreateTNode(rootTView, null, 0, TNodeType.Container, null, null);
|
|
||||||
const rootLView = createLView(
|
|
||||||
null, rootTView, {}, LViewFlags.CheckAlways, null, null, {} as RendererFactory3,
|
|
||||||
{} as Renderer3);
|
|
||||||
const lContainer =
|
|
||||||
createLContainer(mockRNode as RComment, rootLView, mockRNode as RComment, tContainerNode, true);
|
|
||||||
addToViewTree(rootLView, lContainer);
|
|
||||||
|
|
||||||
// Create 10 different embedded view types
|
|
||||||
const embeddedTView = createTView(-1, function() {}, 0, 0, null, null, null, null);
|
|
||||||
|
|
||||||
function createAndInsertEmbeddedView(tView: TView, index: number) {
|
|
||||||
const lView = createLView(
|
|
||||||
rootLView, tView, {}, LViewFlags.CheckAlways, null, null, {} as RendererFactory3,
|
|
||||||
{} as Renderer3);
|
|
||||||
insertView(lView, lContainer, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create 1000 embedded views and add them to the container
|
|
||||||
for (let i = 0; i < 1000; i++) {
|
|
||||||
createAndInsertEmbeddedView(embeddedTView, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// run in the creation mode to set flags etc.
|
|
||||||
renderView(rootLView, rootTView, null);
|
|
||||||
|
|
||||||
// run change detection in the update mode
|
// run change detection in the update mode
|
||||||
console.profile('update');
|
console.profile('update');
|
||||||
for (let i = 0; i < 20000; i++) {
|
for (let i = 0; i < 20000; i++) {
|
||||||
refreshView(rootLView, rootTView, rootTView.template, null);
|
refreshView(rootLView, rootTView, null, null);
|
||||||
}
|
}
|
||||||
console.profileEnd();
|
console.profileEnd();
|
56
packages/core/test/render3/perf/noop_renderer.ts
Normal file
56
packages/core/test/render3/perf/noop_renderer.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, RendererStyleFlags3} from '../../../src/render3/interfaces/renderer';
|
||||||
|
|
||||||
|
export class WebWorkerRenderNode implements RNode, RComment, RText {
|
||||||
|
textContent: string|null = null;
|
||||||
|
parentNode: RNode|null = null;
|
||||||
|
parentElement: RElement|null = null;
|
||||||
|
nextSibling: RNode|null = null;
|
||||||
|
removeChild(oldChild: RNode): RNode { return oldChild; }
|
||||||
|
insertBefore(newChild: RNode, refChild: RNode|null, isViewRoot: boolean): void {}
|
||||||
|
appendChild(newChild: RNode): RNode { return newChild; }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class NoopRenderer implements ProceduralRenderer3 {
|
||||||
|
destroy(): void { throw new Error('Method not implemented.'); }
|
||||||
|
createComment(value: string): RComment { return new WebWorkerRenderNode(); }
|
||||||
|
createElement(name: string, namespace?: string|null|undefined): RElement {
|
||||||
|
return new WebWorkerRenderNode() as any as RElement;
|
||||||
|
}
|
||||||
|
createText(value: string): RText { return new WebWorkerRenderNode(); }
|
||||||
|
destroyNode?: ((node: RNode) => void)|null|undefined;
|
||||||
|
appendChild(parent: RElement, newChild: RNode): void {}
|
||||||
|
insertBefore(parent: RNode, newChild: RNode, refChild: RNode|null): void {}
|
||||||
|
removeChild(parent: RElement, oldChild: RNode, isHostElement?: boolean|undefined): void {}
|
||||||
|
selectRootElement(selectorOrNode: any): RElement { throw new Error('Method not implemented.'); }
|
||||||
|
parentNode(node: RNode): RElement|null { throw new Error('Method not implemented.'); }
|
||||||
|
nextSibling(node: RNode): RNode|null { throw new Error('Method not implemented.'); }
|
||||||
|
setAttribute(el: RElement, name: string, value: string, namespace?: string|null|undefined): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
removeAttribute(el: RElement, name: string, namespace?: string|null|undefined): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
addClass(el: RElement, name: string): void { throw new Error('Method not implemented.'); }
|
||||||
|
removeClass(el: RElement, name: string): void { throw new Error('Method not implemented.'); }
|
||||||
|
setStyle(el: RElement, style: string, value: any, flags?: RendererStyleFlags3|undefined): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
removeStyle(el: RElement, style: string, flags?: RendererStyleFlags3|undefined): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
setProperty(el: RElement, name: string, value: any): void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
setValue(node: RComment|RText, value: string): void { node.textContent = value; }
|
||||||
|
listen(
|
||||||
|
target: RNode|'document'|'window'|'body', eventName: string,
|
||||||
|
callback: (event: any) => boolean | void): () => void {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class NoopRendererFactory implements RendererFactory3 {
|
||||||
|
createRenderer(hostElement: RElement|null, rendererType: null): Renderer3 {
|
||||||
|
return new NoopRenderer();
|
||||||
|
}
|
||||||
|
}
|
42
packages/core/test/render3/perf/setup.ts
Normal file
42
packages/core/test/render3/perf/setup.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import {addToViewTree, createLContainer, createLView, createTNode, createTView, getOrCreateTNode, renderView} from '../../../src/render3/instructions/shared';
|
||||||
|
import {ComponentTemplate} from '../../../src/render3/interfaces/definition';
|
||||||
|
import {TNodeType, TViewNode} from '../../../src/render3/interfaces/node';
|
||||||
|
import {RComment} from '../../../src/render3/interfaces/renderer';
|
||||||
|
import {LView, LViewFlags} from '../../../src/render3/interfaces/view';
|
||||||
|
import {insertView} from '../../../src/render3/node_manipulation';
|
||||||
|
|
||||||
|
import {NoopRenderer, NoopRendererFactory, WebWorkerRenderNode} from './noop_renderer';
|
||||||
|
|
||||||
|
export function setupRootViewWithEmbeddedViews(
|
||||||
|
templateFn: ComponentTemplate<any>| null, consts: number, vars: number,
|
||||||
|
noOfViews: number): LView {
|
||||||
|
// Create a root view with a container
|
||||||
|
const rootTView = createTView(-1, null, 1, 0, null, null, null, null);
|
||||||
|
const tContainerNode = getOrCreateTNode(rootTView, null, 0, TNodeType.Container, null, null);
|
||||||
|
const rootLView = createLView(
|
||||||
|
null, rootTView, {}, LViewFlags.CheckAlways | LViewFlags.IsRoot, null, null,
|
||||||
|
new NoopRendererFactory(), new NoopRenderer());
|
||||||
|
const mockRNode = new WebWorkerRenderNode();
|
||||||
|
const lContainer = createLContainer(
|
||||||
|
mockRNode as RComment, rootLView, mockRNode as RComment, tContainerNode, true);
|
||||||
|
addToViewTree(rootLView, lContainer);
|
||||||
|
|
||||||
|
|
||||||
|
// create test embedded views
|
||||||
|
const embeddedTView = createTView(-1, templateFn, consts, vars, null, null, null, null);
|
||||||
|
const viewTNode = createTNode(rootTView, null, TNodeType.View, -1, null, null) as TViewNode;
|
||||||
|
|
||||||
|
// create embedded views and add them to the container
|
||||||
|
for (let i = 0; i < noOfViews; i++) {
|
||||||
|
const embeddedLView = createLView(
|
||||||
|
rootLView, embeddedTView, {}, LViewFlags.CheckAlways, null, viewTNode,
|
||||||
|
new NoopRendererFactory(), new NoopRenderer());
|
||||||
|
renderView(embeddedLView, embeddedTView, null);
|
||||||
|
insertView(embeddedLView, lContainer, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// run in the creation mode to set flags etc.
|
||||||
|
renderView(rootLView, rootTView, null);
|
||||||
|
|
||||||
|
return rootLView;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user