Please read my post in Telegram: Don't use spread operator with byte arrays
- Use
target.set(source, offset)MDN - Pre-alocate the entire array once
- Don't use
...spreadoperator with bytes
Also, tinybench is a great modern library to do benchmarks.
Please read my post in Telegram: Don't use spread operator with byte arrays
target.set(source, offset) MDN...spread operator with bytesAlso, tinybench is a great modern library to do benchmarks.
| import { randomBytes } from 'node:crypto'; | |
| import { Bench, hrtimeNow } from 'tinybench'; | |
| const bench = new Bench({ | |
| time: 1_000, | |
| now: hrtimeNow, | |
| }); | |
| const bytes1 = randomBytes(5_000); | |
| const bytes2 = randomBytes(3_000); | |
| const bytes3 = randomBytes(2_000); | |
| const totalSize = ( | |
| bytes1.length + | |
| bytes2.length + | |
| bytes3.length | |
| ); | |
| (bench | |
| .add('bytes.set', () => { | |
| const result = new Uint8Array(totalSize); | |
| result.set(bytes1, 0); | |
| result.set(bytes2, bytes1.length); | |
| result.set(bytes3, bytes1.length + bytes2.length); | |
| }) | |
| .add('bytes.set (stages)', () => { | |
| let result = new Uint8Array(); | |
| result = append(result, bytes1); | |
| result = append(result, bytes2); | |
| result = append(result, bytes3); | |
| function append( | |
| bytes1: Uint8Array, | |
| bytes2: Uint8Array | |
| ): Uint8Array { | |
| const result = new Uint8Array( | |
| bytes1.length + | |
| bytes2.length | |
| ); | |
| result.set(bytes1, 0); | |
| result.set(bytes2, bytes1.length); | |
| return result; | |
| } | |
| }) | |
| .add('bytes ...spread', async () => { | |
| new Uint8Array([ | |
| ...bytes1, | |
| ...bytes2, | |
| ...bytes3, | |
| ]); | |
| }) | |
| .add('bytes writer', async () => { | |
| // Uses bytes.set under the hood, | |
| // but enables more readable code. | |
| // ----- | |
| const writer = new BytesWriter({ | |
| size: totalSize, | |
| }); | |
| (writer | |
| .writeBytes(bytes1) | |
| .writeBytes(bytes2) | |
| .writeBytes(bytes3) | |
| ); | |
| }) | |
| ); | |
| await bench.warmup(); | |
| await bench.run(); | |
| console.table( | |
| bench.table() | |
| ); |
| [10,000 BYTES] | |
| ┌──────────────────────┬───────────┬─────────────────┬──────────┬─────────┐ | |
| │ Task Name │ ops/sec │ Avg. Time (ns) │ Margin │ Samples │ | |
| ├──────────────────────┼───────────┼─────────────────┼──────────┼─────────┤ | |
| │ bytes.set │ 674,823 │ 1481.86 │ '±0.50%' │ 674,827 │ <----- WINNER | |
| │ bytes ...spread │ 4,504 │ 221985.41 │ '±0.20%' │ 4,505 │ 149.82 times slower | |
| │ bytes.set (stages) │ 235,420 │ 4247.71 │ '±0.91%' │ 235,421 │ 2.86 times slower | |
| │ bytes writer │ 583,673 │ 1713.28 │ '±0.52%' │ 583,674 │ 1.15 times slower | |
| └──────────────────────┴───────────┴─────────────────┴──────────┴─────────┘ | |
| [1,000 BYTES] | |
| ┌──────────────────────┬───────────┬─────────────────┬──────────┬─────────┐ | |
| │ Task Name │ ops/sec │ Avg. Time (ns) │ Margin │ Samples │ | |
| ├──────────────────────┼───────────┼─────────────────┼──────────┼─────────┤ | |
| │ bytes.set │ 801,084 │ 1248.30 │ '±2.21%' │ 801,085 │ <----- WINNER | |
| │ bytes ...spread │ 43,298 │ 23095.55 │ '±0.16%' │ 43,299 │ 18.50 times slower | |
| │ bytes.set (stages) │ 252,794 │ 3955.78 │ '±3.43%' │ 252,795 │ 3.16 times slower | |
| │ bytes writer │ 692,139 │ 1444.79 │ '±3.35%' │ 692,140 │ 1.15 times slower | |
| └──────────────────────┴───────────┴─────────────────┴──────────┴─────────┘ | |
| [100 BYTES] | |
| ┌──────────────────────┬─────────────┬─────────────────┬──────────┬───────────┐ | |
| │ Task Name │ ops/sec │ Avg. Time (ns) │ Margin │ Samples │ | |
| ├──────────────────────┼─────────────┼─────────────────┼──────────┼───────────┤ | |
| │ bytes.set │ 2,088,572 │ 478.79 │ '±0.28%' │ 2,088,573 │ <----- WINNER | |
| │ bytes ...spread │ 319,625 │ 3128.66 │ '±0.25%' │ 319,626 │ 6.50 times slower | |
| │ bytes.set (stages) │ 852,849 │ 1172.53 │ '±0.27%' │ 852,853 │ 2.44 times slower | |
| │ bytes writer │ 1,269,895 │ 787.46 │ '±0.24%' │ 1,269,897 │ 1.64 times slower | |
| └──────────────────────┴─────────────┴─────────────────┴──────────┴───────────┘ | |
Please add a star. Also, join my Telegram channel for more useful guides and insights on JavaScript/TypeScript development.
Be my guest to comment in the section below or under posts in my Telegram channel.
Need professional consultancy? You can contact me directly.