docs: add `Function Inlining` rules to `PERF_NOTES.md` (#26876)

PR Close #26876
This commit is contained in:
Miško Hevery 2018-10-31 10:42:03 -07:00 committed by Kara Erickson
parent a2929dfd57
commit 683d53db4b
1 changed files with 38 additions and 1 deletions

View File

@ -68,6 +68,43 @@ for (var i = 0, keys = Object.keys(obj); i < keys.length; i++) {
## Recursive functions
Avoid recursive functions when possible because they cannot be inlined.
## Function Inlining
VMs gain a lot of speed by inlining functions which are small (such as getters).
This is because the cost of the value retrieval (getter) is often way less than the cost of making a function call.
VMs use the heuristic of size to determine whether a function should be inline.
Thinking is that large functions probably will not benefit inlining because the overhead of function call is not significant to the overall function execution.
Our goal should be that all of the instructions which are in template function should be inlinable.
Here is an example of code which breaks the inlining and a way to fix it.
```
export function i18nStart(index: number, message: string, subTemplateIndex?: number): void {
const tView = getTView();
if (tView.firstTemplatePass && tView.data[index + HEADER_OFFSET] === null) {
// LOTS OF CODE HERE WHICH PREVENTS INLINING.
}
}
```
Notice that the above function almost never runs because `tView.firstTemplatePass` is usually false.
The application would benefit from inlining, but the large code inside `if` prevents it.
Simple refactoring will fix it.
```
export function i18nStart(index: number, message: string, subTemplateIndex?: number): void {
const tView = getTView();
if (tView.firstTemplatePass && tView.data[index + HEADER_OFFSET] === null) {
i18nStartFirstTemplatePass(tView, index, message, subTemplateIndex)
}
}
export function i18nStartFirstTemplatePass(tView: TView, index: number, message: string, subTemplateIndex?: number): void {
// LOTS OF CODE HERE WHICH PREVENTS INLINING.
}
```
## Loops
Don't use foreach, it can cause megamorphic function calls (depending on the browser) and function allocations.
Don't use `forEach`, it can cause megamorphic function calls (depending on the browser) and function allocations.
It is [a lot slower than regular `for` loops](https://jsperf.com/for-vs-foreach-misko)