我编写了一个功能来帮助输送其他功能。但是它严重缺乏效率。
首先,我编写将包含其他功能的功能。它从standard input
读取并将指定的function
应用于每个输入:
function func_pipe() {
local func="$1" && shift
while ifs='' read -r line || [[ -n "$line" ]]; do
$func $line
done
}
我定义了用于测试目的的模式:
PATTERN="mypattern"
我创建了一个10k行大文件以进行测试:
### Create big file
time for i in $(seq 1 10000); do
echo "$i - here I write the pattern $PATTERN for testing purpose.";
done > bigfile.txt
real 0m38.234s
user 0m10.245s
sys 0m20.050s
我编写将处理我的输入的功能:
function process1() {
echo -e "$@" | egrep "$PATTERN"
}
i处理文件以搜索模式。我使用func_pipe
处理standard input
s。:
echo -e "n[Testing with pipes]"
time cat bigfile.txt
| func_pipe process1
| func_pipe process1
| wc -l
real 1m23.898s
user 1m16.992s
sys 1m54.495s
现在,我将在字符串中构建我的命令,然后稍后再 evaluate
。
首先,我编写一个类似的处理功能,该功能将在字符串中打印管道。注意使处理功能不同的强调:
function _process1() {
echo " | grep "$PATTERN""
}
我定义了我的命令和处理字符串:
cmd="cat bigfile.txt"
cmd_process="$(_process1)$(_process1) | wc -l"
我测试它们:
echo -e "n[Testing with eval]"
time eval "${cmd}${cmd_process}"
real 0m0.014s
user 0m0.015s
sys 0m0.013s
它在瞬间闪烁中做到了。因此,似乎为每个输入的管道功能和读取每个标准输入的功能确实并不高效。至少,我想认为这个问题来自我的实施。我的目标是使它们像管道unix
命令一样高效(cut
,sed
,etc
(。我相信这些命令也从stdin
中读取,所以我是缺少一些方法的人。改善我的包装功能的缺少是什么?
您的两种方法有一个主要区别:第二种唯一一种卵形流程将读取stdin的整个文件,而您的第一种方法将在每个输入行中产生一个GREP进程。
我怀疑这是您观察到的差异的原因。产卵过程很便宜,但不是免费的。
由于外壳,第一个版本也发生了更多的开销(按行读取行 将每行传递到子过程(。
您的func_pipe
应将整个标准输入传递给process1
函数,如果要减少此开销,请不要尝试按线路划分。
只是在bash中阅读速度很慢,对于每行也要分叉一个新过程。