Skip to content

Conversation

@evanlucas
Copy link
Contributor

By manually copying arguments and breaking the try/catch out, we are able to improve the performance of util.format by 20-100% (depending on the types).

Also includes a util.format benchmark.

The numbers:

running ./node util/format.js running ./node_before util/format.js util/format.js n=1000000 type=string: ./node: 7866600 ./node_before: 1705900 ... 361.13% util/format.js n=1000000 type=number: ./node: 7718000 ./node_before: 1778900 ... 333.87% util/format.js n=1000000 type=object: ./node: 1811800 ./node_before: 800160 .... 126.43% util/format.js n=1000000 type=unknown: ./node: 13045000 ./node_before: 2650300 . 392.22% util/format.js n=1000000 type=no-replace: ./node: 1541500 ./node_before: 956760 . 61.11% 

EDIT: I updated the numbers after rebasing on master and with @mscdex's changes included as well.

@evanlucasevanlucas added util Issues and PRs related to the built-in util module. benchmark Issues and PRs related to the benchmark subsystem. performance Issues and PRs related to the performance of Node.js. labels Feb 22, 2016
@evanlucas
Copy link
ContributorAuthor

lib/util.js Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use var here until v8 can optimize let better.

lib/util.js Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, you'll also need to move the var i declaration out and above and change var i = 1; a few lines below to i = 1 to avoid a linter error.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, just noticed that locally. Thanks

@mscdex
Copy link
Contributor

For bonus points, you can change

for(varx=args[i];i<len;x=args[++i]){

to

while(i<len){constx=args[i++];

to avoid an eager deopt due to potential out of bounds access on args.

@evanlucasevanlucasforce-pushed the utilformatbench branch 2 times, most recently from 7a00928 to 91fc8b4CompareFebruary 22, 2016 09:39
@evanlucas
Copy link
ContributorAuthor

Ah, totally missed the case where f is not a string. Added a benchmark and updated for that as well

lib/util.js Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String(f) here can probably just be replaced with just f since it should already be a string at that point.

@evanlucas
Copy link
ContributorAuthor

ooo good catch

@mscdex
Copy link
Contributor

@mscdex
Copy link
Contributor

Just for fun I replaced the regexp + replace function with a simple loop and improved performance an additional 60-200% in the benchmarks included (and no change in the no-replace case) in this PR.

@evanlucas
Copy link
ContributorAuthor

wow, nice

@jasnell
Copy link
Member

Marking this LTS watch but I'd rather this sit for a bit before getting pulled back.

@jasnell
Copy link
Member

LGTM

@evanlucas
Copy link
ContributorAuthor

evanlucasand others added 3 commits March 4, 2016 17:27
By manually copying arguments and breaking the try/catch out, we are able to improve the performance of util.format by 20-100% (depending on the types). PR-URL: nodejs#5360 Reviewed-By: James M Snell <[email protected]>
Replacing the regexp and replace function with a loop improves performance by ~60-200%. PR-URL: nodejs#5360 Reviewed-By: James M Snell <[email protected]>
@evanlucasevanlucas deleted the utilformatbench branch March 4, 2016 23:28
@evanlucasevanlucas merged commit c490b8b into nodejs:masterMar 4, 2016
@MylesBorins
Copy link
Contributor

@jasnell would you want to include this in a future lts?

@jasnell
Copy link
Member

I believe so yes.

@MylesBorins
Copy link
Contributor

@jasnell / @nodejs/lts how much longer to we want this to live before backporting?

@jasnell
Copy link
Member

I haven't heard of any regressions. We may be good on this one
On Jun 30, 2016 5:11 PM, "Myles Borins" [email protected] wrote:

@jasnellhttps://github.com/jasnell / @nodejs/lts
https://github.com/orgs/nodejs/teams/lts how much longer to we want
this to live before backporting?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#5360 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAa2eVV5PJs-GWjQjX7nl55qNJMiSNYGks5qRFtAgaJpZM4HfWa3
.

MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
By manually copying arguments and breaking the try/catch out, we are able to improve the performance of util.format by 20-100% (depending on the types). PR-URL: #5360 Reviewed-By: James M Snell <[email protected]>
MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
Replacing the regexp and replace function with a loop improves performance by ~60-200%. PR-URL: #5360 Reviewed-By: James M Snell <[email protected]>
@MylesBorins
Copy link
Contributor

I've gone ahead and added this to v4.x-staging and will include it in the v4.5.0 rc.

@evanlucas please let me know if there are any accompanying patch's we need to make this work

@MylesBorins
Copy link
Contributor

@evanlucas as a heads up you need to provide the commit before your initial commit when doing the ... syntax to specify a range.

735e0df...c490b8b does not include 735e0df

MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
By manually copying arguments and breaking the try/catch out, we are able to improve the performance of util.format by 20-100% (depending on the types). PR-URL: #5360 Reviewed-By: James M Snell <[email protected]>
MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
Replacing the regexp and replace function with a loop improves performance by ~60-200%. PR-URL: #5360 Reviewed-By: James M Snell <[email protected]>
MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
MylesBorins pushed a commit that referenced this pull request Jul 12, 2016
@evanlucas
Copy link
ContributorAuthor

@thealphanerd there shouldn't be anything else need to land these. Thanks for the heads up on the range syntax as well :]

MylesBorins pushed a commit that referenced this pull request Jul 12, 2016
By manually copying arguments and breaking the try/catch out, we are able to improve the performance of util.format by 20-100% (depending on the types). PR-URL: #5360 Reviewed-By: James M Snell <[email protected]>
MylesBorins pushed a commit that referenced this pull request Jul 12, 2016
Replacing the regexp and replace function with a loop improves performance by ~60-200%. PR-URL: #5360 Reviewed-By: James M Snell <[email protected]>
MylesBorins pushed a commit that referenced this pull request Jul 12, 2016
@MylesBorinsMylesBorins mentioned this pull request Jul 12, 2016
MylesBorins pushed a commit that referenced this pull request Jul 14, 2016
MylesBorins pushed a commit that referenced this pull request Jul 14, 2016
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

benchmarkIssues and PRs related to the benchmark subsystem.performanceIssues and PRs related to the performance of Node.js.utilIssues and PRs related to the built-in util module.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@evanlucas@mscdex@jasnell@MylesBorins