我有一个包含 30M 行的大输入文件,在\r\n. 我决定做一些愚蠢的事情,并通过read -r与xargs(剥离第\r一个,因为xargs似乎无法拆分多个字符)比较计算所有行的速度。这是我的两个命令:
time tr -d '\r' < input.txt | xargs -P 1 -d '\n' -I {} echo "{}" | wc -l
Run Code Online (Sandbox Code Playgroud)
time while read -r p || [ -n "$p" ]; do echo "$p"; done < input.txt | wc -l
Run Code Online (Sandbox Code Playgroud)
在这里,第二种解决方案要快得多。这是为什么?
请注意,我知道这不是计算文件行数的正确方法。这个问题只是出于我观察的兴趣。
Sté*_*las 10
是的,当你怀疑xargs -P 1 -d '\n' -I {} echo "{}",这实际上是一样xargs -rd '\n' -n1的echo是默认的命令,将创建一个进程并执行独立echo的子过程,同时在父等待其终止对输入的每一行。
所以这比在同一个 shell 进程中使用低效的read内置函数和echo内置函数要多得多。
如果xargs您使用 busybox而不是 GNU ,xargs它(至少在某些配置和最新版本中)将在echo内部调用 busybox而无需分叉进程,您会注意到它会比bash循环快得多。
要进行更相关的比较,您应该比较:
tr -d '\r' | xargs -rd'\n' -n1
Run Code Online (Sandbox Code Playgroud)
和
tr -d '\r' |
while IFS= read -r line || [ -n "$line" ]; do
/bin/echo "$line"
done
Run Code Online (Sandbox Code Playgroud)
这可能会给您类似的结果,因为大部分时间将花费在分叉进程和执行独立的echo.
在这里,关于输出seq 3e7和测量pv -al > /dev/null(以每秒a平均lines 数来测量吞吐量),我绕过: