current commit
260327.6 · benchmark: add benchmarks for experimental stream/iter
// File reading throughput benchmark.
// Reads a real file through the three stream APIs.
'use strict';

const common = require('../common.js');
const fs = require('fs');
const { Writable, pipeline } = require('stream');
const tmpdir = require('../../test/common/tmpdir');

tmpdir.refresh();
const filename = tmpdir.resolve(`.removeme-bench-file-read-${process.pid}`);

const bench = common.createBenchmark(main, {
  api: ['classic', 'webstream', 'iter'],
  filesize: [1024 * 1024, 16 * 1024 * 1024, 64 * 1024 * 1024],
  n: [5],
}, {
  flags: ['--experimental-stream-iter'],
});

function main({ api, filesize, n }) {
  // Create fixture file
  const chunk = Buffer.alloc(Math.min(filesize, 64 * 1024), 'abcdefghij');
  const fd = fs.openSync(filename, 'w');
  let remaining = filesize;
  while (remaining > 0) {
    const size = Math.min(remaining, chunk.length);
    fs.writeSync(fd, chunk, 0, size);
    remaining -= size;
  }
  fs.closeSync(fd);

  const totalOps = (filesize * n) / (1024 * 1024);

  switch (api) {
    case 'classic':
      return benchClassic(filesize, n, totalOps);
    case 'webstream':
      return benchWebStream(filesize, n, totalOps);
    case 'iter':
      return benchIter(filesize, n, totalOps);
  }
}

function benchClassic(filesize, n, totalOps) {
  function run(cb) {
    const r = fs.createReadStream(filename);
    const w = new Writable({ write(data, enc, cb) { cb(); } });
    pipeline(r, w, cb);
  }

  // Warmup
  run(() => {
    let i = 0;
    bench.start();
    (function next() {
      if (i++ >= n) {
        fs.unlinkSync(filename);
        return bench.end(totalOps);
      }
      run(next);
    })();
  });
}

function benchWebStream(filesize, n, totalOps) {
  const fsp = require('fs/promises');

  async function run() {
    const fh = await fsp.open(filename, 'r');
    const rs = fh.readableWebStream();
    const ws = new WritableStream({ write() {} });
    await rs.pipeTo(ws);
    await fh.close();
  }

  (async () => {
    // Warmup
    await run();

    bench.start();
    for (let i = 0; i < n; i++) await run();
    fs.unlinkSync(filename);
    bench.end(totalOps);
  })();
}

function benchIter(filesize, n, totalOps) {
  const fsp = require('fs/promises');
  const { pipeTo } = require('stream/iter');

  async function run() {
    const fh = await fsp.open(filename, 'r');
    await pipeTo(fh.pull(), { write() {} });
    await fh.close();
  }

  (async () => {
    // Warmup
    await run();

    bench.start();
    for (let i = 0; i < n; i++) await run();
    fs.unlinkSync(filename);
    bench.end(totalOps);
  })();
}