stdin和命令行参数之间的性能差异


11

对于某些命令,可以将某些输入指定为stdin或命令行参数。

具体来说,假设command可以将stdin输入和文件名用作命令行参数和command < myfilecat myfile | command 并且command myfile可以产生相同的结果。

例如,

当命令是sed

sed s/day/night/ <myfile >new   
sed s/day/night/ myfile >new    
cat myfile | sed s/day/night/ >new

当命令是cat

cat < myfile
cat myfile
  1. 我想知道关于它们的性能是否有一些通用规则,即,其中哪一个通常是最有效的,而哪一个是最低的?
  2. 重定向是否总是比管道更好?

1
我希望每个问这些(重复的)问题的人都能从头开始编写自己的shell作为练习。
Alex

1
请不要使用“谢谢!” 在你的问题。投票回答以表达您的感激之情。
Alex

@Alex:如果这是骗子,请链接到重复项,我们将关闭它。通常,您将避免回答已知重复的问题,并标记它以引起主持人注意。
卡莱布

1
@alex:在哪里可以学习如何编写自己的shell?
蒂姆(Tim)

@Caleb:我敢肯定,过去一个月有人问过2到3次,只是没有链接方便:-p
alex

Answers:


6

cat file | command语法被认为是的无用Cat。在所有选项中,它会降低性能,因为它必须在内核中生成另一个进程。然而,这可能微不足道,但总的来说,这是其他表格所没有的开销。这已涵盖在以下问题上:我是否应该关心不必要的猫?

在其他两种形式之间,实际上没有性能差异。STDIN是一个特殊的文件节点,进程必须像其他任何文件一样打开和读取。传递文件名而不是STDIN只会使它打开另一个文件。

不同之处在于您要寻找的功能/灵活性。

  • 将文件名传递给程序将意味着输入文件是可搜索的。这可能对程序无关紧要,但如果可搜索流,则可以加快某些操作。
  • 了解实际的输入文件可以使您的程序有可能对其进行写入。例如sed -i就地编辑。(注意:由于这必须在幕后创建一个新文件,因此与其他重定向相比,性能没有提高,但这是一个方便的步骤。)
  • 使用Shell重定向使您能够连接多个文件,甚至使用进程重定向。sed [exp] < file1 file2甚至sed [exp] < <(grep command)。有关该用例的详细信息,请参见以下问题:流程替换和管道

流程替换应该可以工作,而无需您传递结果。sed [exp] < <(grep command)将正常工作sed [exp] <(grep command)(因为<(grep command)在命令的长度上创建了一个命名的临时文件,该文件sed完全能够在没有shell辅助的情况下自行打开)。
ShadowRanger

2
  1. 鉴于command file只需打开文件,然后从开始就可以正常工作stdin,几乎没有什么区别。使用shell重定向,您只需提前打开文件(shell即可),而不是打开命令二进制文件本身。

  2. 如果我们在谈论cat file | commandvs. command <file,则首选后者。您不会注意到两者之间的显着性能差异,但是前者不必要地复杂(额外的过程和管道的共享内存缓冲区,并且吞吐量有限。)而且,您不能seek(任意更改文件指针的位置)管道,而您可以在一个普通文件中。当可以seek在输入文件中添加-ing时,某些命令可能会使用更有效的算法。


我会说命令文件比命令<文件更可取,因为该命令可能会进行某种非顺序访问。
2011年

什么会阻止它这样做<file呢?您的观点对于使用输入文件名来推导输出文件名hard是有效的,例如:gzip fileproduces file.gz
alex

也许我不了解重定向在内部如何工作。假设我们将12GB的电影重定向到mplayer / vlc,然后跳到最后。在这种情况下究竟会发生什么?
user606723 2011年

1
Shell打开文件并派生一个子进程,该子进程继承了文件描述符。分叉的过程closes stdin并调用dup打开的文件描述符,因此它将替换旧的文件描述符stdin(在大多数情况下为tty)。播放器本身。在两种情况下文件描述符都是可搜索的,因此当我们跳到最后时,没有用户可检测到的差异。
Alex
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.