New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf(ivy): move attributes array into component def #32798
Conversation
b419ac2
to
b90be9e
Compare
packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts
Outdated
Show resolved
Hide resolved
b90be9e
to
025ba88
Compare
025ba88
to
d110496
Compare
@mhevery I've reworked it based on the feedback. Can you take another look? |
const literal = o.literalArr(constExprs); | ||
|
||
// Try to reuse a literal that's already in the array, if possible. | ||
for (let i = 0; i < this._constants.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going through the constants list every time we see an attribute seems like it might be slower. Could we re-use some of the existing constant pool logic here to de-dupe?
const lView = getLView(); | ||
const tView = lView[TVIEW]; | ||
const tViewConsts = tView.consts; | ||
const consts = tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have we checked yet if there's any perf impact of the extra read using the micro-benchmarks?
Also, wouldn't constIndex
be null if tViewConsts
is null? Could we remove the tViewConsts === null
check?
const consts = tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex]; | |
const consts = constsIndex == null ? null : tViewConsts[constsIndex]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't run any if the benchmarks yet. Also the constsIndex
could be null if we need to skip over it to pass in the localRefs
param. I suppose we can get rid of it once the local refs are in the consts
array.
d110496
to
9e3d17b
Compare
Would it be possible to make It would be particularly useful for the |
Makes sense to me @petebacondarwin. The question is whether we want to get these changes in and do a follow-up that turns it into a function and moves the i18n and references arrays into it. |
I vote to land this and follow up later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but this is still blocked on running the microbenchmarks
Currently Ivy stores the element attributes into an array above the component def and passes it into the relevant instructions, however the problem is that upon minification the array will get a unique name which won't compress very well. These changes move the attributes array into the component def and pass in the index into the instructions instead. Before: ``` const _c0 = ['foo', 'bar']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', 'bar']], template: function() { element(0, 'div', 0); } }); ``` A couple of cases that this PR doesn't handle: * Template references are still in a separate array. * i18n attributes are still in a separate array.
@crisbeto Thanks for doing that! Looks like this PR gives us a slight perf edge, so we're definitely good to merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Can we do a follow up PR:
- embedded template functions should also be moved to
consts
- Also include localization strings in the
consts
. - Change the
ComponentDef.const
to have a function which returns the arrays. The reason for this is that @ocombe and @petebacondarwin need a way to delay the execution of the$localize
until after locale strings are loaded. By putting it into the closure this can be achieved. WhenTView
is created and we copy theconsts
fromComponentDef
to theTView
we can execute the closure which will in turn execute the$localize
and we would cache the resulting values inTView
merge-assistance: global approval |
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Currently Ivy stores the element attributes into an array above the component def and passes it into the relevant instructions, however the problem is that upon minification the array will get a unique name which won't compress very well. These changes move the attributes array into the component def and pass in the index into the instructions instead. Before: ``` const _c0 = ['foo', 'bar']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', 'bar']], template: function() { element(0, 'div', 0); } }); ``` A couple of cases that this PR doesn't handle: * Template references are still in a separate array. * i18n attributes are still in a separate array. PR Close angular#32798
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ```
Follow-up from #32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ``` PR Close #33129
Follow-up from #32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ``` PR Close #33129
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ``` PR Close angular#33129
Follow-up from angular#32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ``` PR Close angular#33129
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Currently Ivy stores the element attributes into an array above the component def and passes it into the relevant instructions, however the problem is that upon minification the array will get a unique name which won't compress very well. These changes move the attributes array into the component def and pass in the index into the instructions instead.
Before:
After:
A couple of cases that this PR doesn't handle: