[英]Command substitution vs process substitution
我试图理解这两个相似命令之间的差异。
aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
<()
需要#!/bin/bash
,但这会让它变慢吗? bash
或sh
进程吗? 我希望使用具有最佳性能的命令。
lastpipe
,则每个管道元素都有一个进程加上替换加上父进程的子shell。 lastpipe
,则管道的最后一个元素将在两种情况下都不exec
,仍然需要相同数量的进程。 /dev/fd/*
的系统上编译的,那么shell将为进程替换创建命名管道。 这可能会影响性能。 $(<...)
除外)。 在mksh和ksh93中,还有${ ;}
样式命令替换,但每个shell都以不同方式实现。 在ksh93中,它可能会也可能不会加速。 在mksh,可能不是。 mksh不支持进程替换,并且zsh不支持(并且无法模拟) BASHPID
,所以我没有调查过它。 命令替换本质上没有什么比Bash中的进程替换更快,但是在read
的情况下head
是多余的,因为你只在那里读取一行。 顺便说一句,总是使用head -n ...
- -1
不可移植。 另外,除非你想让shell破坏输入,否则不要使用不带-r
read
。
提高性能的最佳方法是尽可能多地摆脱叉子和管道。
出于所有意图和目的,您不应该担心所述的性能问题。 99%的执行时间可能由特定命令决定,而不是由进程替换与命令替换的差异决定。 你知道优化的第一定律吗? 别。 特别是如果你牺牲了便携性。 使用$(whatever)
并忘记其他一切。 如果你真的担心性能,那么你需要解决的是命令/管道/分支。 否则你会试图通过挤压眼泪来减肥。
使用Bash's
内置time
基准测试,第一种形式比第二种形式慢。
您可以使用以下方法自行测试:
bash -c 'time PIPELINE...'
两者都创建子壳 - 在第一种情况下使用shell读取并扩展子壳的输出,并且在第二种情况下从shell read
内置读取。
看到:
进程替换绕过由piplines /命令替换创建的子shell。 替换语法由FIFO或FD的名称替换,其中的命令在后台运行。 替换在参数扩展和命令替换的同时执行。
查看与“tee”一起使用的过程替换信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.