-
Notifications
You must be signed in to change notification settings - Fork 37
fix: improve addChild and path performance #1891
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
Conversation
| * Components are separated by '/'. | ||
| */ | ||
| public get path(): string { | ||
| const components = this.scopes.filter(c => c.node.id).map(c => c.node.id); |
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.
Calling filter generates one array, and calling map after creates another array. It should be slightly faster to create a single array and perform filtering inside a for loop.
| throw new Error(`Cannot add children to "${this.path}" during synthesis`); | ||
| } | ||
|
|
||
| if (childName in this._children) { |
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.
From what I tested, array access is slightly faster than using the "in" operator
| if (!childName && this.id) { | ||
| throw new Error(`cannot add a nameless construct to the named scope: ${this.path}`); | ||
| } |
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 don't think this if branch can get called. Here's my reasoning:
addChildis only called if a non-nullscopeis passed to theNodeconstructor.- if a non-null
scopeis passed to theNodeconstructor, andthis.idhas a falsey value (likeundefinedor an empty string), then an error will be thrown in theNodeconstructor beforeaddChildis called. - based on (1) and (2), when
addChildis called, it's guaranteed thatchildNamewill not be a falsey value - the if statement's body only executes if childName takes on a falsey value
I tried coming up with a test case that would actually throw this error but I don't think there's a way.
| if (Object.keys(this._children).length > 1 && Object.keys(this._children).filter(x => !x).length > 0) { | ||
| throw new Error('only a single construct is allowed in a scope if it has an empty name'); | ||
| } |
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 also don't think this branch can ever get called. Here was my reasoning:
- From my other comment,
childNamewill never take on a falsey value (like an empty string). - From (1), the line
this._children[childName] = childlcan never add falsey values as keys tothis._children. - There are no other lines of code that add new keys to
this._children. - Therefore,
this._childrenwill always have keys with truthy values, soObject.keys(this._children).filter(x => !x)can never have a length greater than 0.
mrgrain
left a comment
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.
Ha thanks for that!
eladb
left a comment
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.
👍

Improve the performance of the
constructslibrary by removing several branches in the library's hot paths and switching to some more performant operations.On my laptop, the benchmark I used (shared in a gist here) takes about 5.0-5.3 seconds with the old version of constructs, and about 1.1-1.2 seconds with the new version of constructs.
Misc:
testfolder.npmignoreto reduce the package's npm footprint.