forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathiter-throughput-compression.js
More file actions
104 lines (92 loc) · 2.91 KB
/
Copy pathiter-throughput-compression.js
File metadata and controls
104 lines (92 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Throughput benchmark: gzip compress then decompress round-trip.
// Tests real-world compression performance across stream APIs.
'use strict';
const common = require('../common.js');
const { Readable, Writable, pipeline } = require('stream');
const zlib = require('zlib');
const bench = common.createBenchmark(main, {
api: ['classic', 'webstream', 'iter'],
datasize: [1024 * 1024, 16 * 1024 * 1024, 64 * 1024 * 1024],
n: [5],
}, {
flags: ['--experimental-stream-iter'],
});
const CHUNK_SIZE = 64 * 1024;
function main({ api, datasize, n }) {
const chunk = Buffer.alloc(CHUNK_SIZE, 'abcdefghij');
const totalOps = (datasize * n) / (1024 * 1024);
switch (api) {
case 'classic':
return benchClassic(chunk, datasize, n, totalOps);
case 'webstream':
return benchWebStream(chunk, datasize, n, totalOps);
case 'iter':
return benchIter(chunk, datasize, n, totalOps);
}
}
function benchClassic(chunk, datasize, n, totalOps) {
function run(cb) {
let remaining = datasize;
const r = new Readable({
read() {
if (remaining <= 0) { this.push(null); return; }
const size = Math.min(remaining, chunk.length);
remaining -= size;
this.push(size === chunk.length ? chunk : chunk.subarray(0, size));
},
});
const w = new Writable({ write(data, enc, cb) { cb(); } });
pipeline(r, zlib.createGzip(), zlib.createGunzip(), w, cb);
}
let i = 0;
bench.start();
(function next() {
if (i++ >= n) return bench.end(totalOps);
run(next);
})();
}
function benchWebStream(chunk, datasize, n, totalOps) {
async function run() {
let remaining = datasize;
const rs = new ReadableStream({
pull(controller) {
if (remaining <= 0) { controller.close(); return; }
const size = Math.min(remaining, chunk.length);
remaining -= size;
controller.enqueue(
size === chunk.length ? chunk : chunk.subarray(0, size));
},
});
const ws = new WritableStream({ write() {} });
await rs
.pipeThrough(new CompressionStream('gzip'))
.pipeThrough(new DecompressionStream('gzip'))
.pipeTo(ws);
}
(async () => {
bench.start();
for (let i = 0; i < n; i++) await run();
bench.end(totalOps);
})();
}
function benchIter(chunk, datasize, n, totalOps) {
const { pipeTo } = require('stream/iter');
const { compressGzip, decompressGzip } = require('zlib/iter');
async function run() {
let remaining = datasize;
async function* source() {
while (remaining > 0) {
const size = Math.min(remaining, chunk.length);
remaining -= size;
yield [size === chunk.length ? chunk : chunk.subarray(0, size)];
}
}
await pipeTo(source(), compressGzip(), decompressGzip(),
{ write() {}, writeSync() { return true; } });
}
(async () => {
bench.start();
for (let i = 0; i < n; i++) await run();
bench.end(totalOps);
})();
}