initial import
This commit is contained in:
+211
@@ -0,0 +1,211 @@
|
||||
import { Readable, Writable, Duplex } from 'stream';
|
||||
import { source, sink, duplex } from '../index.js';
|
||||
|
||||
const CHUNK_SIZE = 16384;
|
||||
const CHUNK_COUNT = 100000;
|
||||
|
||||
function createBenchmarkReadable() {
|
||||
const data = Buffer.alloc(CHUNK_SIZE, 'x');
|
||||
let count = 0;
|
||||
return new Readable({
|
||||
highWaterMark: 1024 * 1024,
|
||||
read() {
|
||||
if (count < CHUNK_COUNT) {
|
||||
count++;
|
||||
this.push(data);
|
||||
} else {
|
||||
this.push(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createBenchmarkWritable() {
|
||||
let bytesWritten = 0;
|
||||
const w = new Writable({
|
||||
highWaterMark: 1024 * 1024,
|
||||
write(chunk, encoding, callback) {
|
||||
bytesWritten += chunk.length;
|
||||
callback();
|
||||
}
|
||||
});
|
||||
return w;
|
||||
}
|
||||
|
||||
async function benchmarkSource() {
|
||||
const readable = createBenchmarkReadable();
|
||||
const pushSrc = source(readable);
|
||||
const received = [];
|
||||
let byteCount = 0;
|
||||
|
||||
const start = process.hrtime.bigint();
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
pushSrc.pipe({
|
||||
write(data) {
|
||||
byteCount += data.length;
|
||||
},
|
||||
end(err) {
|
||||
if (err) return reject(err);
|
||||
resolve();
|
||||
},
|
||||
get paused() { return false; },
|
||||
set paused(v) {}
|
||||
});
|
||||
});
|
||||
|
||||
const end = process.hrtime.bigint();
|
||||
const duration = Number(end - start) / 1e9;
|
||||
const throughput = (byteCount / duration / 1024 / 1024).toFixed(2);
|
||||
|
||||
return { duration, throughput, bytes: byteCount };
|
||||
}
|
||||
|
||||
async function benchmarkSink() {
|
||||
const writable = createBenchmarkWritable();
|
||||
const pushSnk = sink(writable);
|
||||
const data = Buffer.alloc(CHUNK_SIZE, 'x');
|
||||
|
||||
const start = process.hrtime.bigint();
|
||||
|
||||
for (let i = 0; i < CHUNK_COUNT; i++) {
|
||||
pushSnk.write(data);
|
||||
}
|
||||
pushSnk.end();
|
||||
|
||||
await new Promise((resolve) => {
|
||||
writable.on('finish', resolve);
|
||||
});
|
||||
|
||||
const end = process.hrtime.bigint();
|
||||
const duration = Number(end - start) / 1e9;
|
||||
const bytes = CHUNK_COUNT * CHUNK_SIZE;
|
||||
const throughput = (bytes / duration / 1024 / 1024).toFixed(2);
|
||||
|
||||
return { duration, throughput, bytes };
|
||||
}
|
||||
|
||||
async function benchmarkDuplex() {
|
||||
const data = Buffer.alloc(CHUNK_SIZE, 'x');
|
||||
let count = 0;
|
||||
let byteCount = 0;
|
||||
|
||||
const duplexStream = new Duplex({
|
||||
highWaterMark: 1024 * 1024,
|
||||
read() {
|
||||
if (count < CHUNK_COUNT) {
|
||||
count++;
|
||||
this.push(data);
|
||||
} else {
|
||||
this.push(null);
|
||||
}
|
||||
},
|
||||
write(chunk, encoding, callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
||||
const pushDup = duplex(duplexStream);
|
||||
|
||||
const start = process.hrtime.bigint();
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
pushDup.pipe({
|
||||
write(data) {
|
||||
byteCount += data.length;
|
||||
},
|
||||
end(err) {
|
||||
if (err) return reject(err);
|
||||
resolve();
|
||||
},
|
||||
get paused() { return false; },
|
||||
set paused(v) {}
|
||||
});
|
||||
});
|
||||
|
||||
const end = process.hrtime.bigint();
|
||||
const duration = Number(end - start) / 1e9;
|
||||
const throughput = (byteCount / duration / 1024 / 1024).toFixed(2);
|
||||
|
||||
return { duration, throughput, bytes: byteCount };
|
||||
}
|
||||
|
||||
async function benchmarkObjectMode() {
|
||||
const arr = Array.from({ length: CHUNK_COUNT }, (_, i) => ({ id: i, value: Math.random() }));
|
||||
let index = 0;
|
||||
|
||||
const readable = new Readable({
|
||||
objectMode: true,
|
||||
highWaterMark: 1024,
|
||||
read() {
|
||||
if (index < arr.length) {
|
||||
this.push(arr[index++]);
|
||||
} else {
|
||||
this.push(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const pushSrc = source(readable);
|
||||
let itemCount = 0;
|
||||
|
||||
const start = process.hrtime.bigint();
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
pushSrc.pipe({
|
||||
write(data) {
|
||||
itemCount++;
|
||||
},
|
||||
end(err) {
|
||||
if (err) return reject(err);
|
||||
resolve();
|
||||
},
|
||||
get paused() { return false; },
|
||||
set paused(v) {}
|
||||
});
|
||||
});
|
||||
|
||||
const end = process.hrtime.bigint();
|
||||
const duration = Number(end - start) / 1e9;
|
||||
const throughput = (itemCount / duration).toFixed(0);
|
||||
|
||||
return { duration, throughput, items: itemCount };
|
||||
}
|
||||
|
||||
async function runBenchmarks() {
|
||||
console.log('stream-to-push-stream benchmarks');
|
||||
console.log('================================');
|
||||
console.log(`Chunk size: ${CHUNK_SIZE} bytes`);
|
||||
console.log(`Chunk count: ${CHUNK_COUNT}`);
|
||||
console.log();
|
||||
|
||||
console.log('Running benchmarks...\n');
|
||||
|
||||
console.log('1. Source (Readable -> Push-Source):');
|
||||
const sourceResult = await benchmarkSource();
|
||||
console.log(` Duration: ${sourceResult.duration.toFixed(3)}s`);
|
||||
console.log(` Throughput: ${sourceResult.throughput} MB/s`);
|
||||
console.log();
|
||||
|
||||
console.log('2. Sink (Writable -> Push-Sink):');
|
||||
const sinkResult = await benchmarkSink();
|
||||
console.log(` Duration: ${sinkResult.duration.toFixed(3)}s`);
|
||||
console.log(` Throughput: ${sinkResult.throughput} MB/s`);
|
||||
console.log();
|
||||
|
||||
console.log('3. Duplex (Duplex -> Push-Duplex):');
|
||||
const duplexResult = await benchmarkDuplex();
|
||||
console.log(` Duration: ${duplexResult.duration.toFixed(3)}s`);
|
||||
console.log(` Throughput: ${duplexResult.throughput} MB/s`);
|
||||
console.log();
|
||||
|
||||
console.log('4. Object Mode (Readable Object -> Push-Source):');
|
||||
const objectResult = await benchmarkObjectMode();
|
||||
console.log(` Duration: ${objectResult.duration.toFixed(3)}s`);
|
||||
console.log(` Throughput: ${objectResult.throughput} items/s`);
|
||||
console.log();
|
||||
|
||||
console.log('Benchmark complete.');
|
||||
}
|
||||
|
||||
runBenchmarks().catch(console.error);
|
||||
Reference in New Issue
Block a user