From 73cb581728566f376782716e76d4f5ad3cfaf204 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 12 Sep 2019 12:44:55 +0200 Subject: [PATCH] perf(ivy): avoid repeat lview reads in pipe instructions (#32633) All of the `pipeBind` instructions call into `isPure` and `unwrapValue` which in turn call `getLView` internally. These internal calls are redundant, because we already have the `LView` from the `load` calls just before it. PR Close #32633 --- packages/core/src/render3/pipe.ts | 43 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/core/src/render3/pipe.ts b/packages/core/src/render3/pipe.ts index 3b9d8bcbcb..ee41c72dc9 100644 --- a/packages/core/src/render3/pipe.ts +++ b/packages/core/src/render3/pipe.ts @@ -12,7 +12,7 @@ import {PipeTransform} from '../change_detection/pipe_transform'; import {getFactoryDef} from './definition'; import {store} from './instructions/all'; import {PipeDef, PipeDefList} from './interfaces/definition'; -import {BINDING_INDEX, HEADER_OFFSET, TVIEW} from './interfaces/view'; +import {BINDING_INDEX, HEADER_OFFSET, LView, TVIEW} from './interfaces/view'; import {ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunctionV} from './pure_function'; import {getLView} from './state'; import {NO_CHANGE} from './tokens'; @@ -85,10 +85,12 @@ function getPipeDef(name: string, registry: PipeDefList | null): PipeDef { * @codeGenApi */ export function ɵɵpipeBind1(index: number, slotOffset: number, v1: any): any { - const pipeInstance = load(getLView(), index); + const lView = getLView(); + const pipeInstance = load(lView, index); return unwrapValue( - isPure(index) ? ɵɵpureFunction1(slotOffset, pipeInstance.transform, v1, pipeInstance) : - pipeInstance.transform(v1)); + lView, isPure(lView, index) ? + ɵɵpureFunction1(slotOffset, pipeInstance.transform, v1, pipeInstance) : + pipeInstance.transform(v1)); } /** @@ -105,10 +107,12 @@ export function ɵɵpipeBind1(index: number, slotOffset: number, v1: any): any { * @codeGenApi */ export function ɵɵpipeBind2(index: number, slotOffset: number, v1: any, v2: any): any { - const pipeInstance = load(getLView(), index); + const lView = getLView(); + const pipeInstance = load(lView, index); return unwrapValue( - isPure(index) ? ɵɵpureFunction2(slotOffset, pipeInstance.transform, v1, v2, pipeInstance) : - pipeInstance.transform(v1, v2)); + lView, isPure(lView, index) ? + ɵɵpureFunction2(slotOffset, pipeInstance.transform, v1, v2, pipeInstance) : + pipeInstance.transform(v1, v2)); } /** @@ -126,9 +130,10 @@ export function ɵɵpipeBind2(index: number, slotOffset: number, v1: any, v2: an * @codeGenApi */ export function ɵɵpipeBind3(index: number, slotOffset: number, v1: any, v2: any, v3: any): any { - const pipeInstance = load(getLView(), index); + const lView = getLView(); + const pipeInstance = load(lView, index); return unwrapValue( - isPure(index) ? + lView, isPure(lView, index) ? ɵɵpureFunction3(slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) : pipeInstance.transform(v1, v2, v3)); } @@ -150,9 +155,10 @@ export function ɵɵpipeBind3(index: number, slotOffset: number, v1: any, v2: an */ export function ɵɵpipeBind4( index: number, slotOffset: number, v1: any, v2: any, v3: any, v4: any): any { - const pipeInstance = load(getLView(), index); + const lView = getLView(); + const pipeInstance = load(lView, index); return unwrapValue( - isPure(index) ? + lView, isPure(lView, index) ? ɵɵpureFunction4(slotOffset, pipeInstance.transform, v1, v2, v3, v4, pipeInstance) : pipeInstance.transform(v1, v2, v3, v4)); } @@ -170,14 +176,16 @@ export function ɵɵpipeBind4( * @codeGenApi */ export function ɵɵpipeBindV(index: number, slotOffset: number, values: [any, ...any[]]): any { - const pipeInstance = load(getLView(), index); + const lView = getLView(); + const pipeInstance = load(lView, index); return unwrapValue( - isPure(index) ? ɵɵpureFunctionV(slotOffset, pipeInstance.transform, values, pipeInstance) : - pipeInstance.transform.apply(pipeInstance, values)); + lView, isPure(lView, index) ? + ɵɵpureFunctionV(slotOffset, pipeInstance.transform, values, pipeInstance) : + pipeInstance.transform.apply(pipeInstance, values)); } -function isPure(index: number): boolean { - return (>getLView()[TVIEW].data[index + HEADER_OFFSET]).pure; +function isPure(lView: LView, index: number): boolean { + return (>lView[TVIEW].data[index + HEADER_OFFSET]).pure; } /** @@ -187,10 +195,9 @@ function isPure(index: number): boolean { * * @param newValue the pipe transformation output. */ -function unwrapValue(newValue: any): any { +function unwrapValue(lView: LView, newValue: any): any { if (WrappedValue.isWrapped(newValue)) { newValue = WrappedValue.unwrap(newValue); - const lView = getLView(); // The NO_CHANGE value needs to be written at the index where the impacted binding value is // stored const bindingToInvalidateIdx = lView[BINDING_INDEX];