Created
November 2, 2025 13:09
-
-
Save mertcanaltin/a8aa09ffee910803227422190fbe65f4 to your computer and use it in GitHub Desktop.
nodejs bench for Buffer.copy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 100 chunks × 4KB streaming test | |
| const { performance } = require('perf_hooks'); | |
| // Prepare test data: 100 chunks of 4KB each | |
| const numChunks = 100; | |
| const chunkSize = 4096; // 4KB | |
| const chunks = []; | |
| for (let i = 0; i < numChunks; i++) { | |
| const chunk = Buffer.allocUnsafe(chunkSize); | |
| // Fill with some data | |
| for (let j = 0; j < chunkSize; j++) { | |
| chunk[j] = (i + j) % 256; | |
| } | |
| chunks.push(chunk); | |
| } | |
| console.log(`Test data: ${numChunks} chunks × ${chunkSize} bytes = ${numChunks * chunkSize} bytes\n`); | |
| // Warmup | |
| for (let i = 0; i < 100; i++) { | |
| const result = Buffer.allocUnsafe(numChunks * chunkSize); | |
| let offset = 0; | |
| for (const chunk of chunks) { | |
| chunk.copy(result, offset); | |
| offset += chunk.length; | |
| } | |
| } | |
| // Test 1: Buffer.copy() | |
| console.log('Test 1: Buffer.copy()'); | |
| const iterations = 100; | |
| let totalTime = 0; | |
| for (let iter = 0; iter < iterations; iter++) { | |
| const result = Buffer.allocUnsafe(numChunks * chunkSize); | |
| let offset = 0; | |
| const start = performance.now(); | |
| for (const chunk of chunks) { | |
| chunk.copy(result, offset); | |
| offset += chunk.length; | |
| } | |
| const end = performance.now(); | |
| totalTime += (end - start); | |
| } | |
| const avgTime = totalTime / iterations; | |
| const perChunkTime = avgTime / numChunks; | |
| const throughputMBs = (numChunks * chunkSize / 1024 / 1024) / (avgTime / 1000); | |
| console.log(` Average time: ${avgTime.toFixed(4)}ms`); | |
| console.log(` Per-chunk: ${(perChunkTime * 1000).toFixed(2)}μs`); | |
| console.log(` Throughput: ${throughputMBs.toFixed(2)} MB/s`); | |
| // Test 2: TypedArray.set() for comparison | |
| console.log('\n Test 2: TypedArray.set() (baseline)'); | |
| totalTime = 0; | |
| for (let iter = 0; iter < iterations; iter++) { | |
| const result = Buffer.allocUnsafe(numChunks * chunkSize); | |
| let offset = 0; | |
| const start = performance.now(); | |
| for (const chunk of chunks) { | |
| result.set(chunk, offset); | |
| offset += chunk.length; | |
| } | |
| const end = performance.now(); | |
| totalTime += (end - start); | |
| } | |
| const avgTimeSet = totalTime / iterations; | |
| const perChunkTimeSet = avgTimeSet / numChunks; | |
| const throughputSetMBs = (numChunks * chunkSize / 1024 / 1024) / (avgTimeSet / 1000); | |
| console.log(`Average time: ${avgTimeSet.toFixed(4)}ms`); | |
| console.log(`Per-chunk: ${(perChunkTimeSet * 1000).toFixed(2)}μs`); | |
| console.log(`Throughput: ${throughputSetMBs.toFixed(2)} MB/s`); | |
| // Comparison | |
| console.log('\n Comparison:'); | |
| const speedup = avgTime / avgTimeSet; | |
| const overhead = ((avgTime - avgTimeSet) / avgTimeSet * 100); | |
| console.log(`Buffer.copy() is ${speedup.toFixed(2)}x slower than TypedArray.set()`); | |
| console.log(`Overhead: ${overhead.toFixed(1)}%`); | |
| // Correctness check | |
| console.log('\n Correctness check:'); | |
| const testResult = Buffer.allocUnsafe(numChunks * chunkSize); | |
| let offset = 0; | |
| for (const chunk of chunks) { | |
| chunk.copy(testResult, offset); | |
| offset += chunk.length; | |
| } | |
| let correct = true; | |
| for (let i = 0; i < numChunks; i++) { | |
| const chunkOffset = i * chunkSize; | |
| for (let j = 0; j < chunkSize; j++) { | |
| const expected = (i + j) % 256; | |
| if (testResult[chunkOffset + j] !== expected) { | |
| correct = false; | |
| break; | |
| } | |
| } | |
| if (!correct) break; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment