Skip to content
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(NODE-4194): improve objectId constructor performance #498

Merged
merged 9 commits into from
May 5, 2022

Conversation

nbbeeken
Copy link
Contributor

@nbbeeken nbbeeken commented Apr 27, 2022

Description

What is changing?

Gating ensureBuffer with an instanceof check should avoid the reletively expensive Buffer.from call.

What is the motivation for this change?

Improve the performance of creating an ObjectId from a buffer.

Double check the following

  • Ran npm run lint script
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: <type>(NODE-xxxx)<!>: <description>
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

@nbbeeken
Copy link
Contributor Author

@addaleax This change would revert a bits of #429 and #432. The thinking is that the instanceof check can succeed for nodejs environments dodging the Buffer.from call, and in environments where the prototype chain doesn't match we still fall back to calling .from. Any thoughts on this?

Copy link
Contributor

@addaleax addaleax left a comment

Choose a reason for hiding this comment

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

@nbbeeken I don’t see any downsides in terms of correctness. I remember that instanceof could be quite slow on some older-but-not-that-old V8 versions, so it might be worth checking the performance impact across Node.js versions.

In the long run, I think the best solution would be to just use Uint8Array everywhere anyway :)

src/objectid.ts Show resolved Hide resolved
src/ensure_buffer.ts Outdated Show resolved Hide resolved
@nbbeeken nbbeeken marked this pull request as ready for review May 3, 2022 15:44
@nbbeeken nbbeeken requested a review from dariakp May 3, 2022 15:44
src/ensure_buffer.ts Outdated Show resolved Hide resolved
Copy link
Member

@durran durran left a comment

Choose a reason for hiding this comment

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

My only comment would be to up the iterations in the benchmark to get a more accurate representation of performance once it's warmed up. Here are the differences on my machine on 10.000 vs 1.000.000 iterations - it's far less of a discrepancy.

Iterations: 10000

BSON@current local
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00283865ms on average
new Oid(buf) take 0.00018213ms on average

[email protected]
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00303077ms on average
new Oid(buf) take 0.00059272ms on average

[email protected]
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00203647ms on average
new Oid(buf) take 0.00031121ms on average
Iterations: 1000000

BSON@current local
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00206223ms on average
new Oid(buf) take 0.00013110ms on average

[email protected]
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00150312ms on average
new Oid(buf) take 0.00020934ms on average

[email protected]
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00098606ms on average
new Oid(buf) take 0.00014574ms on average

@Uzlopak
Copy link
Contributor

Uzlopak commented May 5, 2022

What did you use to bench?

@nbbeeken
Copy link
Contributor Author

nbbeeken commented May 5, 2022

@durran I bumped the iterations and I added system info print out

- cpu: Intel(R) Core(TM) i5-8279U CPU @ 2.40GHz
- cores: 8
- os: darwin
- ram: 16GB
- iterations: 1,000,000

BSON@current local
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00236919ms on average
new Oid(buf) take 0.00009414ms on average

[email protected]
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00156644ms on average
new Oid(buf) take 0.00018286ms on average

[email protected]
deserialize({ oid, string }, { validation: { utf8: false } }) takes 0.00113818ms on average
new Oid(buf) take 0.00011388ms on average

@durran durran merged commit be5fe3e into main May 5, 2022
@durran durran deleted the NODE-4194/oid-performance branch May 5, 2022 20:24
@harrisonhunter
Copy link

Hello! Is there a planned date for the next release of the package?

Waiting for this performance improvement to be shipped to release a different update in another project so just curious if there is a timeline

@nbbeeken
Copy link
Contributor Author

@harrisonhunter The improvement is now available in v4.6.4 🚀

@harrisonhunter
Copy link

Awesome! Thank you very much

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants