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-6344): Improve ObjectId.isValid(string) performance #708

Merged
merged 3 commits into from
Sep 17, 2024

Conversation

SeanReece
Copy link
Contributor

@SeanReece SeanReece commented Aug 22, 2024

Description

This MR improves performance of using ObjectId.isValid('some string') to check if a string is a valid hex representation of an ObjectId. We frequently call this function to check if a user's input is valid (for example, when creating a document that links to other document(s)).

Performance tests

Test Ops/s (Main) Ops/s (New) % Improvement
bson#new ObjectId(string) 3,173,643 ops/sec 3,299,153 ops/sec 3.95%
bson#isValid 5,513,041 ops/sec 22,529,639 ops/sec 308.66%
bson#isValid uppercase 5,498,098 ops/sec 21,776,208 ops/sec 296.07%
bson#isValid invalid end 131,657 ops/sec 22,592,719 ops/sec 17,060.24%
bson#isValid invalid start 132,751 ops/sec 152,311,298 ops/sec 114,634.47%

There is a drastic performance improvement when checking for invalid strings since throwing/catching errors is expensive.

What is changing?

Is there new documentation needed for these changes?

None

What is the motivation for this change?

Release Highlight

Fill in title or leave empty for no highlight

Double check the following

  • Ran npm run check:lint script
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: type(NODE-xxxx)[!]: description
    • Example: feat(NODE-1234)!: rewriting everything in coffeescript
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

@SeanReece
Copy link
Contributor Author

Not sure if you wanted a Jira created since this is such a small change, but I could create one if necessary.

@SeanReece SeanReece changed the title perf: Improve isValid performance with strings perf: Improve ObjectId.isValid(string) performance Aug 22, 2024
@baileympearson
Copy link
Contributor

Hey @SeanReece - I don't believe we have benchmarks for this method. Could you share your benchmarking script so I can test and reproduce?

@SeanReece
Copy link
Contributor Author

SeanReece commented Aug 27, 2024

@baileympearson Sure thing. I just threw together a simple benchmark since I can't get bson-bench to run. If you pull this branch locally, change the name in package.json to bson-isvalid and run an npm run build then you can import bson main and this branch alongside each other.

var Benchmark = require("benchmark");
const bson = require("bson");
const bsonVAL = require("bson-isvalid");

var suite = new Benchmark.Suite();

suite
  // Test calling isValid with a valid objectId hex
  .add("bson#isValid", function () {
    bson.ObjectId.isValid("6683fe22cd402749418c7e2b");
  })
  .add("bsonVAL#isValid", function () {
    bsonVAL.ObjectId.isValid("6683fe22cd402749418c7e2b");
  })

   // Test calling isValid with an INVALID objectId hex
  .add("bson#isValid with invalid string", function () {
    bson.ObjectId.isValid("6683fE22cd402749418c7e2x");
  })
  .add("bsonVAL#isValid with invalid string", function () {
    bsonVAL.ObjectId.isValid("6683fE22cd402749418c7e2x");
  })
  .on("cycle", function (event) {
    console.log(String(event.target));
  })
  .on("complete", function () {
    console.log("Fastest is " + this.filter("fastest").map("name"));
  })
  .run({ async: true });

@baileympearson
Copy link
Contributor

@SeanReece Thanks - I see the same behavior.

I'll bring this up with the team later this week.

@durran
Copy link
Member

durran commented Sep 5, 2024

@SeanReece just as the other PR for isValid I've rebased this one as well.

@durran durran self-assigned this Sep 6, 2024
@W-A-James W-A-James changed the title perf: Improve ObjectId.isValid(string) performance perf(NODE-6344): Improve ObjectId.isValid(string) performance Sep 13, 2024
@W-A-James W-A-James self-requested a review September 13, 2024 18:56
@W-A-James W-A-James assigned W-A-James and unassigned durran Sep 13, 2024
Copy link
Contributor

@nbbeeken nbbeeken left a comment

Choose a reason for hiding this comment

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

Now we do have benchmarks merged for this helper! Also we're better set up to add any helper to our CI so after it is improved we can check if any future changes regress it or make it better. (check out test/bench/custom/readme.md if you're curious)

src/objectid.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@nbbeeken nbbeeken left a comment

Choose a reason for hiding this comment

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

LGTM!

@nbbeeken nbbeeken merged commit 064ba91 into mongodb:main Sep 17, 2024
8 checks passed
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