我想了解这两个类似命令之间的差异。命令替换vs进程替换
aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
- 我知道
<()
需要#!/bin/bash
,但它使得它更慢? - 他们是否创造了相同数量的亚壳?
- 他们是否需要相同数量的
bash
或sh
流程?
我正在寻找使用最佳性能的命令。
我想了解这两个类似命令之间的差异。命令替换vs进程替换
aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
<()
需要#!/bin/bash
,但它使得它更慢?bash
或sh
流程?我正在寻找使用最佳性能的命令。
lastpipe
,则每个管道元素都有一个进程,并且有一个用于替换加上父进程的子shell。lastpipe
启用,该管道将exec
的不分叉在这两种情况下,仍然需要相同数量的进程的最后一个元素。/dev/fd/*
的系统上编译,外壳将创建一个名为工艺替代管道代替。这可能会影响性能。$(<...)
)。在mksh和ksh93中,还有${ ;}
样式命令替换,但每个shell都以不同的方式实现它。在ksh93中,它可能会或可能不会加速。在mksh中,可能不是。 mksh不支持进程替换,并且zsh不支持(并且无法模拟)BASHPID
,所以我没有研究它。没有什么本质上快约比猛砸一个进程替换命令替换,但head
是在read
的情况下,多余的,因为你只是读一行在那里。顺便说一句,总是使用head -n ...
- -1
是不便携的。另外,除非您希望外壳破坏输入,否则不要使用read
而不使用-r
。
Benchmarking与Bash's
内置time
,第一种形式比第二种形式慢。
你可以测试它自己:
bash -c 'time PIPELINE...'
两个创建子shell - 从背景壳阅读和扩大其在第一种情况下一个子shell的输出,与外壳的read
内置阅读第二个过程。
参见:
在这里提高性能的最佳方式是让尽可能多的,你可以摆脱叉子和管道。
对于所有意图和目的,您不应该担心所述的性能问题。执行时间的99%很可能由特定命令决定,而不是过程替换与命令替换之间的差异。你知道优化的第一个规律吗?别。尤其是如果你牺牲可移植性。使用$(whatever)
并忘记其他所有内容。如果您真的担心性能问题,那就是您需要解决的命令/管道/分支。否则,你试图通过挤压眼泪来减肥。
进程替换绕过了由管道/命令替换创建的子shell。替换语法被替换为FIFO或FD的名称,其中的命令在后台运行。 替代作为参数扩展和命令替换同时执行。
查看与“tee”一起使用的过程替换信息。
嗯,这个说法并不完全正确。希望你不介意我已经为你调整了一下。在这两种情况下都有“文件描述符”,并且两者都会生成一个子shell,至少在Bash中也总是暗含至少一个分支。在我的更广泛的测试中,“read -rx <(...)'”和“'x = $(...)'”之间的区别几乎无法用小输入迭代,对于单个大输入,分配的速度稍快(与预期的一样),但在最初的问题中,两种解决方案都是奇数和次优的。 – ormaaj 2013-03-14 20:48:45
没问题'兄弟,感谢编辑。 – 2013-03-15 00:31:14