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(uuid): make bytesToUuid() up to 100x faster #5655

Merged
merged 1 commit into from
Aug 8, 2024

Conversation

babiabeo
Copy link
Contributor

@babiabeo babiabeo commented Aug 8, 2024

The implementation is based on npm:uuid stringify().

Benchmark result and code
cpu: Intel(R) Core(TM) i3-6006U CPU @ 2.00GHz
runtime: deno 1.45.5 (x86_64-pc-windows-msvc)

file:///D:/coding/project/javascript/deno/console/mod.ts
benchmark      time (avg)        iter/s             (min … max)       p75       p99      p995
--------------------------------------------------------------- -----------------------------

group 10 uuids
old            36.98 µs/iter      27,042.4       (32 µs … 1.01 ms) 33.2 µs 100.6 µs 159.3 µs
new              528 ns/iter   1,893,939.4     (400 ns … 909.7 µs) 500 ns 1 µs 1.1 µs

summary
  new
   70.04x faster than old

group 100 uuids
old           367.56 µs/iter       2,720.7    (338.5 µs … 1.83 ms) 350.7 µs 675.9 µs 726.9 µs
new             3.51 µs/iter     284,615.6     (3.34 µs … 3.66 µs) 3.58 µs 3.66 µs 3.66 µs

summary
  new
   104.61x faster than old

group 1000 uuids
old             3.65 ms/iter         273.9     (3.42 ms … 5.05 ms) 3.73 ms 4.71 ms 5.05 ms
new               37 µs/iter      27,024.8      (34 µs … 737.1 µs) 34.6 µs 75.5 µs 94.9 µs

summary
  new
   98.67x faster than old

group 10000 uuids
old            37.35 ms/iter          26.8    (35.4 ms … 46.21 ms) 37.34 ms 46.21 ms 46.21 ms
new           369.83 µs/iter       2,703.9    (349.4 µs … 1.17 ms) 357.7 µs 681.5 µs 806.6 µs

summary
  new
   101x faster than old

const hexTable: string[] = [];

for (let i = 0; i < 256; ++i) {
  hexTable.push(i < 0x10 ? "0" + i.toString(16) : i.toString(16));
}

function bytesToUuid_new(bytes: number[] | Uint8Array): string {
  return (
    hexTable[bytes[0]!]! +
    hexTable[bytes[1]!]! +
    hexTable[bytes[2]!]! +
    hexTable[bytes[3]!]! +
    "-" +
    hexTable[bytes[4]!]! +
    hexTable[bytes[5]!]! +
    "-" +
    hexTable[bytes[6]!]! +
    hexTable[bytes[7]!]! +
    "-" +
    hexTable[bytes[8]!]! +
    hexTable[bytes[9]!]! +
    "-" +
    hexTable[bytes[10]!]! +
    hexTable[bytes[11]!]! +
    hexTable[bytes[12]!]! +
    hexTable[bytes[13]!]! +
    hexTable[bytes[14]!]! +
    hexTable[bytes[15]!]!
  ).toLowerCase();
}

function bytesToUuid_old(bytes: number[] | Uint8Array): string {
  const bits = [...bytes].map((bit) => {
    const s = bit.toString(16);
    return bit < 0x10 ? "0" + s : s;
  });
  return [
    ...bits.slice(0, 4),
    "-",
    ...bits.slice(4, 6),
    "-",
    ...bits.slice(6, 8),
    "-",
    ...bits.slice(8, 10),
    "-",
    ...bits.slice(10, 16),
  ].join("");
}

for (let i = 0; i < 4; ++i) {
  const uuids: Uint8Array[] = [];
  const size = 10 ** (i + 1);

  for (let j = 0; j < size; ++j) {
    // UUID v4
    const uuid = crypto.getRandomValues(new Uint8Array(16));
    uuid[6] = 0x40 | (uuid[6] & 0x0f);
    uuid[8] = 0x80 | (uuid[8] & 0x3f);
    uuids.push(uuid);
  }

  Deno.bench("old", { group: `${size} uuids` }, () => {
    for (const uuid of uuids) {
      bytesToUuid_old(uuid);
    }
  });

  Deno.bench("new", { group: `${size} uuids` }, () => {
    for (const uuid of uuids) {
      bytesToUuid_new(uuid);
    }
  });
}

@babiabeo babiabeo requested a review from kt3k as a code owner August 8, 2024 04:35
@github-actions github-actions bot added the uuid label Aug 8, 2024
Copy link

codecov bot commented Aug 8, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.21%. Comparing base (96d7020) to head (71941f3).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5655      +/-   ##
==========================================
- Coverage   96.21%   96.21%   -0.01%     
==========================================
  Files         470      470              
  Lines       38205    38216      +11     
  Branches     5549     5550       +1     
==========================================
+ Hits        36760    36770      +10     
- Misses       1403     1404       +1     
  Partials       42       42              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@iuioiua iuioiua left a comment

Choose a reason for hiding this comment

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

Great work! Thank you.

@iuioiua iuioiua merged commit 0333255 into denoland:main Aug 8, 2024
13 checks passed
@babiabeo babiabeo deleted the perf-bytesToUuid branch August 8, 2024 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants