Answers:
是的,它减慢了速度。尽管它实际上是由内核维护的,但它基本上确实有未写入数据的队列—所有程序都具有该队列,除非它们明确要求。
例如,这是一个使用的琐碎管道pv
,这很不错,因为它显示了传输速率:
$ pv -s 50g -S -pteba /dev/zero | cat > /dev/null
50GiB 0:00:09 [ 5.4GiB/s] [===============================================>] 100%
现在,让我们tee
在其中添加一个,甚至不写多余的副本,而只是转发它:
$ pv -s 50g -S -pteba /dev/zero | tee | cat > /dev/null
50GiB 0:00:20 [2.44GiB/s] [===============================================>] 100%
因此,这要慢很多,甚至什么也没做!这是Tee内部将STDIN复制到STDOUT的开销。(有趣的是,pv
在其中增加一秒钟的pv
速度为5.19GiB / s,因此,它比tee
。pv
使用的速度要快得多splice(2)
,tee
可能不会。)
无论如何,让我们看看如果我告诉tee
写入磁盘上的文件会发生什么。它的启动速度相当快(〜800MiB / s),但随着它的发展,它一直在减速-最终降至〜100MiB / s,这基本上是磁盘写入带宽的100%。(快速启动是由于内核将磁盘写缓存在缓存中,而磁盘写速度的降低是内核拒绝让缓存无限增长。)
以上是最坏的情况。上面使用管道以最快的速度吐出数据。我能想到的在现实世界中的唯一用途是将原始YUV数据传递到/传递ffmpeg
。
当您以较低的速率发送数据时(因为您正在处理它们,等等),其效果将大大降低。
毕竟这不足为奇
> POSIX说,
描述
该三通工具应标准输入复制到标准输出,零个或多个文件进行复印。该三通实用不得缓冲输出。
还有那个
理据
缓冲要求意味着不允许tee使用ISO C标准的完全缓冲或行缓冲写入。这并不意味着tee必须先读取1个字节,然后再写入1个字节。
因此,在不解释“ rationale”的情况下,tee
可能一次最多只能读取和写入多达多少字节,但每次缓冲区中都可以容纳多少字节,每次写入时都会刷新输出。
是的,根据应用程序的不同,效率可能会很低-因此,请随意删除/注释其中的任何内容:
https : //github.com/coreutils/coreutils/blob/master/src/tee.c#L208
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L224
tee
运行速度更快?