【问题标题】:How to correctly fork a read-stream into 3 compression streams for benchmarking computation?如何正确地将读取流分叉为 3 个压缩流以进行基准计算?
【发布时间】:2020-08-08 20:27:41
【问题描述】:

我想将从一个简单的 .txt 文件创建的 readStream 分叉为 3 个压缩流(gzip、brotli 和 deflate),以便计算每个文件压缩所花费的时间。我当前的代码如下所示:

import {createReadStream, createWriteStream} from 'fs';
import zlib from 'zlib';

const main = () => {
    const filename = 'file.txt';
    const fileStream = createReadStream(filename);
    const compressions = {
        createGzip: 'gz',
        createBrotliCompress: 'br',
        createDeflate: 'deflate'
    };
    let {length} = Object.keys(compressions);
    const timings = {};
    for (const [module, ext] of Object.entries(compressions)) {
        timings[module] = Date.now();
        fileStream
            .pipe(zlib[module]())
            .pipe(createWriteStream(`${filename}.${ext}`))
            .on('finish', () => {
                timings[module] = `it took ${Date.now()-timings[module]}ms`;
                if (!--length)
                    console.log(timings);
            });
    }
};

main();

但是,当我运行脚本时,每次压缩的结果总是大致相同,这意味着必须在 fileStream 本身关闭时触发“完成”事件,而不是针对每个压缩写入流。我该如何正确实施呢?

{
  createGzip: 'it took 3161ms',
  createBrotliCompress: 'it took 3169ms',
  createDeflate: 'it took 3155ms'
}

【问题讨论】:

    标签: node.js stream


    【解决方案1】:

    将单个源限制为多个接收器的速率

    当通过管道将流传输到多个接收器时,最慢的接收器的执行将限制读取流的块速率。

    在 OP 的场景中,当三个接收器中的任何一个发出其写入缓冲区已满(“背压”)的信号时,读取流将暂停从“file.txt”读取块。因此,最高效的接收器将不得不等待最慢的接收器处理其缓冲区 - 时间或多或少相同。

    可以通过为每个接收器创建单独的读取流或按顺序运行性能测试来解决此问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-22
      • 2016-11-29
      • 1970-01-01
      • 2014-03-14
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 2017-03-13
      相关资源
      最近更新 更多