我想了解这两种类似的命令之间的差异。
aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
- 我知道,
<()
要求#!/bin/bash
,但使得它更慢? - 难道他们创建子shell中的一样多吗?
- 他们是否需要相同数量
bash
或sh
进程?
我期待使用命令具有最佳性能。
我想了解这两种类似的命令之间的差异。
aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
<()
要求#!/bin/bash
,但使得它更慢? bash
或sh
进程? 我期待使用命令具有最佳性能。
lastpipe
未启用,则每个管道元素加上无论是替代加父进程子shell进程。 lastpipe
启用,管道的最后一个元素将exec
不分叉在这两种情况下,仍然需要相同数量的进程。 /dev/fd/*
,外壳将创建命名管道的过程,而不是替代。 这可能会影响性能。 $(<...)
的一切,除了猛砸支持它)。 在mksh和ksh93的,另外还有${ ;}
风格命令替换,但每个不同的壳实现这一点。 在ksh93的,它可能会或可能不会给出一个加速。 在mksh,大概不会。 mksh不支持进程替换和zsh中不支持(并没有办法模拟的) BASHPID
,所以我还没有看进去。 没有什么本质上快约比猛砸一个进程替换命令替换,但head
是在的情况下,多余的read
,因为你只读取一行那里。 顺便说一句,总是用head -n ...
- -1
是不可移植。 另外,不要使用read
没有-r
,除非你希望shell裂伤输入。
在这里提高性能的最佳方式是让尽可能多的,你可以摆脱叉子和管道。
对于所有意图和目的,说明你不应该担心性能问题。 的执行时间99%是可能由特定的命令,而不是在处理取代对命令取代的差值来确定。 你知道最优化的第一定律? 别。 特别是如果你牺牲便携性。 使用$(whatever)
,忘记了一切。 如果你确实担心性能,你需要解决的命令/管/叉。 否则,你想从你的眼睛挤眼泪减肥。
标杆Bash's
内置time
,第一种形式比第二慢。
你可以自己与测试:
bash -c 'time PIPELINE...'
这两种创建子shell -与外壳的阅读和扩大一个子shell在第一种情况下的输出,与外壳的read
内置在第二后台进程读取。
看到:
进程替换绕过由piplines /命令替换创建子shell。 该替换语法由FIFO或FD的名称代替,并且在其内部的指令是在后台运行。 的取代是在同一时间作为参数扩展和命令替换进行 。
看看与使用过程代替信息“三通”为好。
http://mywiki.wooledge.org/ProcessSubstitution