You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using ulidx in my project and was concerned about its performance based on benchmarks. While the built-in functionality seemed slow (compared to uuid v7 for example), I decided to investigate further.
Local Machine Benchmark
Here is the result of the benchmark on my local machine, a Mac M1 16 Go
I profiled ulidx (for Node.js only with --prof) to pinpoint the performance bottleneck. The results indicated that the encodeRandom method was the primary culprit. Upon closer inspection, I observed that this method calls crypto.getRandomValues 16 times per ulid generation, which seemed excessive.
Proposed Solution: Buffered PRNG
To address this, I implemented a custom PRNG that reduces the number of calls to crypto.getRandomValues while using a larger buffer size. Here's the code:
This custom PRNG generates random values from a pre-filled buffer, reducing the number of calls to crypto.getRandomValues.
Integration with Benchmark
I incorporated the BufferedPRNG class into the benchmark to compare performance:
constbufferedPRNG_2=newBufferedPRNG(2);constbufferedPRNG_4=newBufferedPRNG(4);constbufferedPRNG_16=newBufferedPRNG(16);constbufferedPRNG_32=newBufferedPRNG(32);constbufferedPRNG_64=newBufferedPRNG(64);suite.add("ulid with bufferedPRNG 2",function(){ulid(undefined,bufferedPRNG_2.next);});// ... similar tests for other buffer sizes
Benchmark Results:
Simple ulid: 27,561 ops/sec ±0.76% (90 runs)
ulid with timestamp: 26,556 ops/sec ±0.85% (93 runs)
ulid with bufferedPRNG 2: 74,244 ops/sec ±0.69% (93 runs)
ulid with bufferedPRNG 4: 137,098 ops/sec ±0.38% (97 runs)
ulid with bufferedPRNG 16: 381,865 ops/sec ±0.35% (97 runs)
ulid with bufferedPRNG 32: 531,374 ops/sec ±0.52% (96 runs)
ulid with bufferedPRNG 64: 668,991 ops/sec ±0.20% (98 runs)
The results demonstrate significant performance improvements. Using a buffer size of 16 (which is the minimum required for a single ulid) yields a roughly 14x speedup.
Request for Feedback
Please let me know if there are any errors in my implementation or approach. I'm open to any suggestions because I plan to use this optimization in my project.
The text was updated successfully, but these errors were encountered:
Hello,
I'm using ulidx in my project and was concerned about its performance based on benchmarks. While the built-in functionality seemed slow (compared to uuid v7 for example), I decided to investigate further.
Local Machine Benchmark
Here is the result of the benchmark on my local machine, a Mac M1 16 Go
Profiling and Bottleneck Identification:
I profiled ulidx (for Node.js only with --prof) to pinpoint the performance bottleneck. The results indicated that the
encodeRandom
method was the primary culprit. Upon closer inspection, I observed that this method callscrypto.getRandomValues
16 times per ulid generation, which seemed excessive.Proposed Solution: Buffered PRNG
To address this, I implemented a custom PRNG that reduces the number of calls to
crypto.getRandomValues
while using a larger buffer size. Here's the code:This custom PRNG generates random values from a pre-filled buffer, reducing the number of calls to
crypto.getRandomValues
.Integration with Benchmark
I incorporated the
BufferedPRNG
class into the benchmark to compare performance:Benchmark Results:
The results demonstrate significant performance improvements. Using a buffer size of 16 (which is the minimum required for a single ulid) yields a roughly 14x speedup.
Request for Feedback
Please let me know if there are any errors in my implementation or approach. I'm open to any suggestions because I plan to use this optimization in my project.
The text was updated successfully, but these errors were encountered: