是否有存在较大的性能差异:管与临时文件
- 过程的书写到一个临时文件,进程B读数文件
- 进程A写入一个管道,而进程B读从该管
我很想知道Windows和* nix的答案是什么。
编辑:我应该问:缓冲区缓存是否消除了临时文件和管道之间的区别?
是否有存在较大的性能差异:管与临时文件
我很想知道Windows和* nix的答案是什么。
编辑:我应该问:缓冲区缓存是否消除了临时文件和管道之间的区别?
一个很大的区别是,使用管道,进程A和B可以同时运行,以便B在A完成生产之前处理来自A的输出。此外,管道的大小是有限的,所以A将不能产生比B消耗的数据更多的数据;它会等待B赶上。
如果数据量很大,那么写入临时文件涉及磁盘活动,即使仅用于创建并销毁该文件。数据可能会留在内存缓冲池中 - 所以没有磁盘I/O - 即使是出乎意料的大文件。写入管道“从不”涉及写入磁盘。
最大的区别在于第一种方法实际上使用磁盘存储,而管道将使用内存(除非您真的很迂腐并开始考虑交换空间)。
性能方面,内存比磁盘(几乎总是)要快。对于所有操作系统而言,这应该是正确的。
使用临时文件的唯一时间是真正有意义的是,如果进程B必须检查多遍数据(如某些种类的视频编码)。对于这种用途,整个数据流将需要缓冲,如果有足够的数据是,它可能会否定内存优势。因此,对于多遍(搜索绑定)操作,请使用临时文件。
请参阅,我想知道磁盘缓存是否会消除管道和临时文件之间的区别。 –
最大的问题是:当进程A写入一个*文件*时,进程B不会做任何事情(直到完成)。当进程A写入* pipe *时,进程B可以立即开始读取。所以,即使操作系统缓存了整个文件,你仍然需要等到A完成。是的,可以“流”一个文件(就像tail -f一样),但是在你看到任何东西之前,你仍然必须等待A刷新。所以再次使用管道,除非你需要寻找。 –
@Chris我不认为进程B必须等到直到进程A已经刷新到文件。如果进程B甚至在进程A完成之前开始读取文件,则没有发生任何错误。进程B的请求将从缓冲区本身完成。它不需要等到更改提交到磁盘。还是我误解了? –
除非我理解管道完全离开墙壁,否则答案是肯定的。
写入临时文件涉及磁盘访问以及相关的开销。
写入管道,并从中读取,发生在内存中。快多了。
我认为一个实际的答案可能会有所帮助。我正在加速优化我使用的脚本大约4个步骤。我将其设置为使用管道和非管道方法。这是在Windows 7 64位下。
我得到了3%的减速不使用管道。对我而言,这是值得的,因为现在我可以在每一步之间停下来并更新窗口标题,而当窗口标题完全是一个命令时,我无法更新窗口标题。个人而言,我会以3%的命中率打开窗口标题。为了好奇,我打量一个大于20M的文件,然后将它传递给专门的perl脚本来修改结果,然后使用SORT.EXE中的窗口对它们进行排序,然后使用cygwin的UNIQ.EXE对它们进行uniq'ing,然后重新刷新这些相同的结果以获得基于ANSI的grep结果着色。大部分时间都花在分类阶段。
+1 - 你唯一没有明确回答的是,对Windows和Unix来说这是一样的。 (我怀疑会有什么区别,但它是在原来的问题。) – OverZealous
@OverZealous:公平点。我的答案比Windows更适用于Unix。 Windows有时会获得与Unix略有不同的结果,但我认为我的观点在Windows上是有效的。我不确定Windows管道从不涉及写入磁盘。 –