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

feat: improved v4 performance #435

Merged
merged 4 commits into from May 6, 2020
Merged

Conversation

awwit
Copy link
Contributor

@awwit awwit commented May 5, 2020

Performance is increased by using a single rnds8 buffer to generate random numbers (as in browser version).

Changes affect only the v1 and v4.

Benchmark master:

uuidv1() x 1,640,551 ops/sec ±0.76% (91 runs sampled)
uuidv1() fill existing array x 7,369,911 ops/sec ±0.49% (96 runs sampled)
uuidv4() x 389,271 ops/sec ±1.39% (92 runs sampled)
uuidv4() fill existing array x 407,681 ops/sec ±1.62% (91 runs sampled)
uuidv3() x 142,615 ops/sec ±0.81% (87 runs sampled)
uuidv5() x 141,386 ops/sec ±1.09% (87 runs sampled)

Benchmark this branch:

uuidv1() x 1,653,982 ops/sec ±0.91% (90 runs sampled)
uuidv1() fill existing array x 7,383,926 ops/sec ±0.66% (93 runs sampled)
uuidv4() x 471,989 ops/sec ±0.53% (93 runs sampled)
uuidv4() fill existing array x 484,766 ops/sec ±0.48% (96 runs sampled)
uuidv3() x 141,146 ops/sec ±1.18% (85 runs sampled)
uuidv5() x 147,054 ops/sec ±1.13% (90 runs sampled)

}

return buf || bytesToUuid(rnds);
return bytesToUuid(rnds);
Copy link
Member

@broofa broofa May 5, 2020

Choose a reason for hiding this comment

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

Gotta return buf if it's passed in. (This should have been caught by unit tests. Can you add a test to check this?)

Suggested change
return bytesToUuid(rnds);
return buf || bytesToUuid(rnds);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@broofa sure, I can add test for this case.

But the code can be seen that the buffer is returned after it is filled:
https://github.com/uuidjs/uuid/pull/435/files#diff-8988f35cbc1e6b5ea7f9cb52a4bfa0f2R26

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

@awwit I just realized that we currently do two things: fill the passed buffer and return it. But we only test for filling, not for the returned buffer.

Since we don't know if anybody relies on the fact, that our methods fill the provided buffer and return it, it would be a good opportunity to add another test case that test for the return value when a buffer is passed.

@awwit awwit requested a review from broofa May 5, 2020 15:03
Copy link
Member

@broofa broofa left a comment

Choose a reason for hiding this comment

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

Whups! Sorry, my bad.

Copy link
Member

@ctavan ctavan left a comment

Choose a reason for hiding this comment

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

Nice work and sorry for the delay in review!

I think we have an opportunity here to add a test case here, see comments.

src/v4.js Outdated
@@ -2,10 +2,10 @@ import rng from './rng.js';
import bytesToUuid from './bytesToUuid.js';

function v4(options, buf, offset) {
const i = (buf && offset) || 0;
const start = (buf && offset) || 0;
Copy link
Member

Choose a reason for hiding this comment

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

Define this variable only in the if(buf) scope below, it's not needed outside. It then simplifies to offset | 0.

An alternative would be to use default arguments. We'd have to check how efficient the bable'd code is then though (in terms of bundlesize).

@@ -2,10 +2,10 @@ import rng from './rng.js';
import bytesToUuid from './bytesToUuid.js';

function v4(options, buf, offset) {
const i = (buf && offset) || 0;
const start = (buf && offset) || 0;

if (typeof options === 'string') {
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to finally get rid of this legacy old API:

uuidv4('binary');

Out of scope for this PR, but I've taken note in #437.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ctavan ok, I will do it a bit later (deprecated)

}

return buf || bytesToUuid(rnds);
return bytesToUuid(rnds);
Copy link
Member

Choose a reason for hiding this comment

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

@awwit I just realized that we currently do two things: fill the passed buffer and return it. But we only test for filling, not for the returned buffer.

Since we don't know if anybody relies on the fact, that our methods fill the provided buffer and return it, it would be a good opportunity to add another test case that test for the return value when a buffer is passed.

@awwit awwit requested a review from ctavan May 6, 2020 20:55
Copy link
Member

@ctavan ctavan left a comment

Choose a reason for hiding this comment

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

👏

@ctavan ctavan merged commit bf4af0d into uuidjs:master May 6, 2020
ctavan added a commit that referenced this pull request May 6, 2020
* Simplify the v3/v5 tests for the buffer api
* Add test cases to v1/v3/v5 to ensure that if passing a buffer as
  second parameter that buffer is not only filled but also returned. For
  v4 this has already been added in #435.
ctavan added a commit that referenced this pull request May 7, 2020
* Simplify the v3/v5 tests for the buffer api
* Add test cases to v1/v3/v5 to ensure that if passing a buffer as
  second parameter that buffer is not only filled but also returned. For
  v4 this has already been added in #435.
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.

None yet

3 participants