From 33fab2693083a401ca7df5da5564696e489c3458 Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Mon, 12 Aug 2019 12:31:15 +0200 Subject: [PATCH] test(ivy): remove code duplication from node perf benchmarks (#32104) PR Close #32104 --- .../perf/{interpolation => }/BUILD.bazel | 12 +- packages/core/test/render3/perf/README.md | 11 ++ .../test/render3/perf/interpolation/README.md | 11 -- .../test/render3/perf/interpolation/index.ts | 132 +++--------------- .../perf/noop_change_detection/BUILD.bazel | 21 --- .../perf/noop_change_detection/index.ts | 43 +----- .../core/test/render3/perf/noop_renderer.ts | 56 ++++++++ packages/core/test/render3/perf/setup.ts | 42 ++++++ 8 files changed, 144 insertions(+), 184 deletions(-) rename packages/core/test/render3/perf/{interpolation => }/BUILD.bazel (58%) create mode 100644 packages/core/test/render3/perf/README.md delete mode 100644 packages/core/test/render3/perf/interpolation/README.md delete mode 100644 packages/core/test/render3/perf/noop_change_detection/BUILD.bazel create mode 100644 packages/core/test/render3/perf/noop_renderer.ts create mode 100644 packages/core/test/render3/perf/setup.ts diff --git a/packages/core/test/render3/perf/interpolation/BUILD.bazel b/packages/core/test/render3/perf/BUILD.bazel similarity index 58% rename from packages/core/test/render3/perf/interpolation/BUILD.bazel rename to packages/core/test/render3/perf/BUILD.bazel index 4eafa0b41e..a7d7f6d4ee 100644 --- a/packages/core/test/render3/perf/interpolation/BUILD.bazel +++ b/packages/core/test/render3/perf/BUILD.bazel @@ -13,9 +13,17 @@ ts_library( ) ng_rollup_bundle( - name = "bundle", - entry_point = ":index.ts", + name = "interpolation", + entry_point = ":interpolation/index.ts", deps = [ ":perf_lib", ], ) + +ng_rollup_bundle( + name = "noop_change_detection", + entry_point = ":noop_change_detection/index.ts", + deps = [ + ":perf_lib", + ], +) \ No newline at end of file diff --git a/packages/core/test/render3/perf/README.md b/packages/core/test/render3/perf/README.md new file mode 100644 index 0000000000..25c8b47e78 --- /dev/null +++ b/packages/core/test/render3/perf/README.md @@ -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 \ No newline at end of file diff --git a/packages/core/test/render3/perf/interpolation/README.md b/packages/core/test/render3/perf/interpolation/README.md deleted file mode 100644 index b936eeecac..0000000000 --- a/packages/core/test/render3/perf/interpolation/README.md +++ /dev/null @@ -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 \ No newline at end of file diff --git a/packages/core/test/render3/perf/interpolation/index.ts b/packages/core/test/render3/perf/interpolation/index.ts index ed88e843e8..5ae83f3924 100644 --- a/packages/core/test/render3/perf/interpolation/index.ts +++ b/packages/core/test/render3/perf/interpolation/index.ts @@ -1,92 +1,25 @@ import {ɵɵelementEnd, ɵɵelementStart} from '../../../../src/render3/instructions/element'; 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 {ɵɵtextInterpolate} from '../../../../src/render3/instructions/text_interpolation'; import {RenderFlags} from '../../../../src/render3/interfaces/definition'; -import {TNodeType, TViewNode} from '../../../../src/render3/interfaces/node'; -import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, RendererFactory3, RendererStyleFlags3} from '../../../../src/render3/interfaces/renderer'; -import {LViewFlags, TView} from '../../../../src/render3/interfaces/view'; -import {insertView} from '../../../../src/render3/node_manipulation'; - -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; } -} - -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: ` - -
- - - - - - - - - - -
-
` -}) -class TestComponent { -} */ - - +import {TVIEW} from '../../../../src/render3/interfaces/view'; +import {setupRootViewWithEmbeddedViews} from '../setup'; +`
+ + + + + + + + + + +
+`; function TestInterpolationComponent_ng_template_0_Template(rf: RenderFlags, ctx: any) { if (rf & 1) { ɵɵelementStart(0, 'div'); @@ -147,36 +80,9 @@ function TestInterpolationComponent_ng_template_0_Template(rf: RenderFlags, ctx: } -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 | 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); +const rootLView = + setupRootViewWithEmbeddedViews(TestInterpolationComponent_ng_template_0_Template, 21, 10, 1000); +const rootTView = rootLView[TVIEW]; // run change detection in the update mode console.profile('update'); diff --git a/packages/core/test/render3/perf/noop_change_detection/BUILD.bazel b/packages/core/test/render3/perf/noop_change_detection/BUILD.bazel deleted file mode 100644 index 4eafa0b41e..0000000000 --- a/packages/core/test/render3/perf/noop_change_detection/BUILD.bazel +++ /dev/null @@ -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", - ], -) diff --git a/packages/core/test/render3/perf/noop_change_detection/index.ts b/packages/core/test/render3/perf/noop_change_detection/index.ts index 5f6eab0559..b983950e0d 100644 --- a/packages/core/test/render3/perf/noop_change_detection/index.ts +++ b/packages/core/test/render3/perf/noop_change_detection/index.ts @@ -1,44 +1,13 @@ -import {addToViewTree, createLContainer, createLView, createTView, getOrCreateTNode, refreshView, renderView} from '../../../../src/render3/instructions/shared'; -import {TNodeType} from '../../../../src/render3/interfaces/node'; -import {RComment, Renderer3, RendererFactory3} from '../../../../src/render3/interfaces/renderer'; -import {LViewFlags, TView} from '../../../../src/render3/interfaces/view'; -import {insertView} from '../../../../src/render3/node_manipulation'; +import {refreshView} from '../../../../src/render3/instructions/shared'; +import {TVIEW} from '../../../../src/render3/interfaces/view'; +import {setupRootViewWithEmbeddedViews} from '../setup'; -class WebWorkerRenderNode {} - -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); +const rootLView = setupRootViewWithEmbeddedViews(null, 0, 0, 1000); +const rootTView = rootLView[TVIEW]; // run change detection in the update mode console.profile('update'); for (let i = 0; i < 20000; i++) { - refreshView(rootLView, rootTView, rootTView.template, null); + refreshView(rootLView, rootTView, null, null); } console.profileEnd(); \ No newline at end of file diff --git a/packages/core/test/render3/perf/noop_renderer.ts b/packages/core/test/render3/perf/noop_renderer.ts new file mode 100644 index 0000000000..98473d44c9 --- /dev/null +++ b/packages/core/test/render3/perf/noop_renderer.ts @@ -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(); + } +} \ No newline at end of file diff --git a/packages/core/test/render3/perf/setup.ts b/packages/core/test/render3/perf/setup.ts new file mode 100644 index 0000000000..917b426259 --- /dev/null +++ b/packages/core/test/render3/perf/setup.ts @@ -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| 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; +} \ No newline at end of file