| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
TypeScript Bot (@typescript-bot) perf test this faster |
Sorry, something went wrong.
|
Heya Daniel Rosenwasser (@DanielRosenwasser), I've started to run the abridged perf test suite on this PR at f671ea7. You can monitor the build here. Update: The results are in! |
Sorry, something went wrong.
|
Daniel Rosenwasser (@DanielRosenwasser) Comparison Report - main..50225
System
Hosts
Scenarios
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sorry, something went wrong.
|
TypeScript Bot (@typescript-bot) perf test this faster |
Sorry, something went wrong.
|
Heya Daniel Rosenwasser (@DanielRosenwasser), I've started to run the abridged perf test suite on this PR at e42cfaf. You can monitor the build here. Update: The results are in! |
Sorry, something went wrong.
|
Daniel Rosenwasser (@DanielRosenwasser) Comparison Report - main..50225
System
Hosts
Scenarios
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sorry, something went wrong.
|
TypeScript Bot (@typescript-bot) test this |
Sorry, something went wrong.
|
Heya Daniel Rosenwasser (@DanielRosenwasser), I've started to run the parallelized Definitely Typed test suite on this PR at e42cfaf. You can monitor the build here. |
Sorry, something went wrong.
|
Heya Daniel Rosenwasser (@DanielRosenwasser), I've started to run the extended test suite on this PR at e42cfaf. You can monitor the build here. |
Sorry, something went wrong.
|
Heya Daniel Rosenwasser (@DanielRosenwasser), I've started to run the perf test suite on this PR at e42cfaf. You can monitor the build here. Update: The results are in! |
Sorry, something went wrong.
|
Heya Daniel Rosenwasser (@DanielRosenwasser), I've started to run the diff-based user code test suite on this PR at e42cfaf. You can monitor the build here. Update: The results are in! |
Sorry, something went wrong.
|
Daniel Rosenwasser (@DanielRosenwasser) |
Sorry, something went wrong.
|
Heya Daniel Rosenwasser (@DanielRosenwasser), I've run the RWC suite on this PR - assuming you're on the TS core team, you can view the resulting diff here. |
Sorry, something went wrong.
|
Daniel Rosenwasser (@DanielRosenwasser)
CompilerComparison Report - main..50225
System
Hosts
Scenarios
TSServerComparison Report - main..50225
System
Hosts
Scenarios
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sorry, something went wrong.
|
I wonder if the same benefit could be found in visitEachChild as well, or potentially any of the main visitor functions in each transformer. This does create an array with quite a bit of empty space due to how many tokens don't have or need a visitor. I wonder if an object literal would have better or worse performance metrics, i.e.: const forEachChildTable: Partial<Record<SyntaxKind, ForEachChildFunction>> = {
[SyntaxKind.QualifiedName]: forEachQualifiedName,
[SyntaxKind.TypeParameter]: forEachTypeParameter,
// etc.
}; |
Sorry, something went wrong.
If an object has identical perf, then I'd assume it's an indication that the array being constructed is sparse - but we need the look-up to be fast. If there's an easy way to create a definitely-packed array, then I'll switch to it here. All the tests do admittedly indicate higher memory usage - but more than I would've expected.
It's definitely worth playing with, especially since visitEachChild tends to be pretty much identical to forEachChild. I don't currently see a difference with checkExpressionWorker though, but I'm playing with it over at #50228. |
Sorry, something went wrong.
There was a problem hiding this comment.
Binding isn't very important as a percentage of tsc execution time, but this should help in editor scenarios where we rebind regularly.
Sorry, something went wrong.
| @@ -95,6 +95,979 @@ namespace ts { | |||
| return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta"; | |||
| } | |||
|
|
|||
| type ForEachChildFunction = <T>(node: any, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray<Node>) => T | undefined) => T | undefined; | |||
|
|
|||
| const forEachChildTable = new Array<ForEachChildFunction>(SyntaxKind.Count); | |||
There was a problem hiding this comment.
Some thoughts on this initialization mechanism:
Sorry, something went wrong.
There was a problem hiding this comment.
Yes, AFAIK the size argument doesn't actually make this a compact array or anything, hence them trying to add a Array.withCapacity instead or something.
Sorry, something went wrong.
|
Daniel Rosenwasser (@DanielRosenwasser) piles of people have signed off on this PR; should we merge it for 4.9? |
Sorry, something went wrong.
|
It sounds like Ron and Jake are both on board with introducing an internal HasChildren type, and then using an object to enforce that everything is set correctly. I think that's a good idea, and we could always swap around the implementations if we don't like these. So I think we should get one more sign-off on Ron's change first at #50266. Once that's in, I'll update this PR to leverage the same HasChildren trick. |
Sorry, something went wrong.
|
TypeScript Bot (@typescript-bot) perf test this faster |
Sorry, something went wrong.
|
Heya Daniel Rosenwasser (@DanielRosenwasser), I've started to run the abridged perf test suite on this PR at cc9ebf0. You can monitor the build here. Update: The results are in! |
Sorry, something went wrong.
|
Because integration with the HasChildren union is such a pain - because forEachChild doesn't account for Identifiers with children, and because visitEachChild doesn't account for any JSDoc nodes - I'm going to defer it to a different PR. I want to be able to untangle the perf wins here with whatever new stuff that might introduce. |
Sorry, something went wrong.
| // TODO: should we separate these branches out? | ||
| visitNode(cbNode, (node as CallExpression).questionDotToken) || |
There was a problem hiding this comment.
I'll do this for a follow-up change.
Sorry, something went wrong.
|
Daniel Rosenwasser (@DanielRosenwasser) Comparison Report - main..50225
System
Hosts
Scenarios
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sorry, something went wrong.
|
Those perf results make me happy every time I see them. |
Sorry, something went wrong.
| node.typeExpression.kind === SyntaxKind.JSDocTypeExpression | ||
| ? visitNode(cbNode, node.typeExpression) || | ||
| visitNode(cbNode, node.fullName) || | ||
| (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)) | ||
| : visitNode(cbNode, node.fullName) || | ||
| visitNode(cbNode, node.typeExpression) || | ||
| (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment))); |
There was a problem hiding this comment.
The indentation here makes it a bit difficult to read.
Sorry, something went wrong.
There was a problem hiding this comment.
I agree, it's awful - but I believe it's from the original code. I'll fix it up in the HasChildren PR.
Sorry, something went wrong.
There was a problem hiding this comment.
I guess I have some lints I have to fix so... I guess I'll fix now.
Sorry, something went wrong.
|
This was a welcome addition. Nice work Daniel Rosenwasser (@DanielRosenwasser) I'm just going to leave this here as something I've noticed. About enums, switches and performance in V8. V8 doesn't like switches with enums, it does however deal with const enums very differently. I wonder what would happen if the SyntaxKind enum was made into a const enum (and you kept the switch). Changing the SyntaxKind enum into a cost enum creates other problems but I think the performance "problem" with the switch statement has more to do so that it isn't being generated into a jump table in machine code when you don't use literal integer numbers (SMIs) as case labels. I don't remember the exact number but I had a switch with 250+ cases in it and when I changed from enum to const enum it made a huge difference. |
Sorry, something went wrong.
SyntaxKind is defined as a const enum internally, so it was using literal integers for case labels. It's likely we were running afoul of some other issue that resulted in a suboptimal compiled representation. |
Sorry, something went wrong.
Oh really, interesting! Thanks for letting me know. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
forEachChild is one of the core pieces of machinery we have for traversing nodes in our trees. It's coded using a fairly large switch statement; however, while reading up on an emulator built in JavaScript (https://artemis.sh/2022/08/07/emulating-calculators-fast-in-js.html), the author called out that most engines do not seem to do the jump-table optimization that some compilers use for switch statements.
So this change introduces a function table for all of forEachChild.
In some other experimentation (namely #50245) it seems like the failure to optimize might have more to do with the function size than the switch/case itself. Regardless, this change seems to cut off around 50ms - 150ms from each perf test's compile time, and speeds up several operations in the language service.