如果感兴趣,是否有关于Bash中功能调用有多贵的任何来源?我希望它们比直接在其中执行代码慢几倍,但我似乎无法找到任何相关内容。
答案 0 :(得分:9)
我真的不同意在使用bash编程时不应该担心性能。这实际上是一个非常好的问题。
这是一个可能的基准,比较内置true
和命令true
,其完整路径是/bin/true
在我的机器上。
在我的机器上:
$ time for i in {0..1000}; do true; done
real 0m0.004s
user 0m0.004s
sys 0m0.000s
$ time for i in {0..1000}; do /bin/true; done
real 0m2.660s
user 0m2.880s
sys 0m2.344s
惊人!只需要一个进程(在我的机器上)就浪费了大约2到3毫秒!
因此,下次您要处理一些大型文本文件时,您将避免管道cat
,grep
s,awk
s,{{(延迟)长链1}} s,cut
s,tr
s,sed
s,head
s,tail
s。此外,unix管道也非常慢(这将是你的下一个问题?)。
想象一下,你有一个1000行的文件,如果在每行中你放了一个you-name-it
,那么cat
然后是grep
然后是sed
(不,不要不要笑,你可以通过浏览这个网站上的帖子看得更糟!),然后你已经浪费了(在我的机器上)至少2 * 4 * 1000 = 8000ms = 8s只是分叉愚蠢和无用的过程。 / p>
更新。要回答有关管道的评论......
子弹很慢:
awk
惊人!每个子壳超过2ms(在我的机器上)。
管道也很慢(这应该是明显的,因为它们涉及子壳):
$ time for i in {1..1000}; do (true); done
real 0m2.465s
user 0m2.812s
sys 0m2.140s
惊人!每个管道超过4ms(在我的机器上),所以管道只需2ms(减去子壳的时间)。
$ time for i in {1..1000}; do true | true; done
real 0m4.769s
user 0m5.652s
sys 0m4.240s
所以这很快。
好的,您可能还希望通过创建文件来查看它:
$ time for i in {1..1000}; do true > file; done
real 0m0.014s
user 0m0.008s
sys 0m0.008s
仍然很快。
在你的评论中,你提到:
$ rm file*; time for i in {1..1000}; do true > file$i; done
real 0m0.030s
user 0m0.008s
sys 0m0.016s
VS
sed '' filein > filetmp; sed '' filetmp > fileout
(当然,最好的方法是使用sed '' filein | sed '' > fileout
的单个实例(通常是可能的),但这不能回答这个问题。)
让我们检查出来:
一个有趣的方式:
sed
因此使用管道而不是使用临时文件(对于sed)似乎更快。实际上,可以在不键入行的情况下理解这一点:在管道中,只要第一个$ rm file*
$ > file
$ time for i in {1..1000}; do sed '' file | sed '' > file$i; done
real 0m5.842s
user 0m4.752s
sys 0m5.388s
$ rm file*
$ > file
$ time for i in {1..1000}; do sed '' file > filetmp$i; sed '' filetmp$i > file$i; done
real 0m6.723s
user 0m4.812s
sys 0m5.800s
吐出某些内容,第二个sed
就会开始处理数据。在第二种情况下,第一个sed
完成其工作,然后第二个sed
完成其工作。
因此,我们的实验并不是确定管道是否比重定向更好的好方法。
流程替换怎么样?
sed
哇,这很慢!嘿,但观察用户和系统CPU的使用情况:远远少于其他两种可能性(如果有人可以解释那个......)