Skip to content

Commit

Permalink
feat: improve performance of v1 string representation (#453)
Browse files Browse the repository at this point in the history
Pre-allocate a fixed size array instead of an empty array when no array is passed.
  • Loading branch information
awwit authored May 25, 2020
1 parent 88ce3ca commit 0ee0b67
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 23 deletions.
8 changes: 7 additions & 1 deletion examples/benchmark/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ suite
uuidv1();
})
.add('uuidv1() fill existing array', function () {
uuidv1(null, array, 0);
try {
uuidv1(null, array, 0);
} catch (err) {
// The spec (https://tools.ietf.org/html/rfc4122#section-4.2.1.2) defines that only 10M/s v1
// UUIDs can be generated on a single node. This library throws an error if we hit that limit
// (which can happen on modern hardware and modern Node.js versions).
}
})
.add('uuidv4()', function () {
uuidv4();
Expand Down
38 changes: 17 additions & 21 deletions src/bytesToUuid.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,30 @@ for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).substr(1));
}

function bytesToUuid(buf, offset) {
const i = offset || 0;

const bth = byteToHex;

function bytesToUuid(buf, offset = 0) {
// Note: Be careful editing this code! It's been tuned for performance
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
return (
bth[buf[i + 0]] +
bth[buf[i + 1]] +
bth[buf[i + 2]] +
bth[buf[i + 3]] +
byteToHex[buf[offset + 0]] +
byteToHex[buf[offset + 1]] +
byteToHex[buf[offset + 2]] +
byteToHex[buf[offset + 3]] +
'-' +
bth[buf[i + 4]] +
bth[buf[i + 5]] +
byteToHex[buf[offset + 4]] +
byteToHex[buf[offset + 5]] +
'-' +
bth[buf[i + 6]] +
bth[buf[i + 7]] +
byteToHex[buf[offset + 6]] +
byteToHex[buf[offset + 7]] +
'-' +
bth[buf[i + 8]] +
bth[buf[i + 9]] +
byteToHex[buf[offset + 8]] +
byteToHex[buf[offset + 9]] +
'-' +
bth[buf[i + 10]] +
bth[buf[i + 11]] +
bth[buf[i + 12]] +
bth[buf[i + 13]] +
bth[buf[i + 14]] +
bth[buf[i + 15]]
byteToHex[buf[offset + 10]] +
byteToHex[buf[offset + 11]] +
byteToHex[buf[offset + 12]] +
byteToHex[buf[offset + 13]] +
byteToHex[buf[offset + 14]] +
byteToHex[buf[offset + 15]]
).toLowerCase();
}

Expand Down
4 changes: 3 additions & 1 deletion src/v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let _lastNSecs = 0;
// See https://github.com/uuidjs/uuid for API details
function v1(options, buf, offset) {
let i = (buf && offset) || 0;
const b = buf || [];
const b = buf || new Array(16);

options = options || {};
let node = options.node || _nodeId;
Expand All @@ -27,6 +27,7 @@ function v1(options, buf, offset) {
// system entropy. See #189
if (node == null || clockseq == null) {
const seedBytes = options.random || (options.rng || rng)();

if (node == null) {
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
node = _nodeId = [
Expand All @@ -38,6 +39,7 @@ function v1(options, buf, offset) {
seedBytes[5],
];
}

if (clockseq == null) {
// Per 4.2.2, randomize (14 bit) clockseq
clockseq = _clockseq = ((seedBytes[6] << 8) | seedBytes[7]) & 0x3fff;
Expand Down

0 comments on commit 0ee0b67

Please sign in to comment.