Skip to content
Permalink
Browse files

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
  • Loading branch information...
crisbeto authored and kara committed Sep 12, 2019
1 parent 527ce3b commit 73cb581728566f376782716e76d4f5ad3cfaf204
Showing with 25 additions and 18 deletions.
  1. +25 −18 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<any> {
* @codeGenApi
*/
export function ɵɵpipeBind1(index: number, slotOffset: number, v1: any): any {
const pipeInstance = load<PipeTransform>(getLView(), index);
const lView = getLView();
const pipeInstance = load<PipeTransform>(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<PipeTransform>(getLView(), index);
const lView = getLView();
const pipeInstance = load<PipeTransform>(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<PipeTransform>(getLView(), index);
const lView = getLView();
const pipeInstance = load<PipeTransform>(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<PipeTransform>(getLView(), index);
const lView = getLView();
const pipeInstance = load<PipeTransform>(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<PipeTransform>(getLView(), index);
const lView = getLView();
const pipeInstance = load<PipeTransform>(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 (<PipeDef<any>>getLView()[TVIEW].data[index + HEADER_OFFSET]).pure;
function isPure(lView: LView, index: number): boolean {
return (<PipeDef<any>>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];

0 comments on commit 73cb581

Please sign in to comment.
You can’t perform that action at this time.