私は30M行を含む大きな入力ファイルを持っています\r\n
。私は愚かなことをし、read -r
すべての行を計算する速度を比較することにしました(2文字以上を分割することは不可能に見えるので、xargs
最初の行を削除します)。私の2つのコマンドは次のとおりです。\r
xargs
time tr -d '\r' < input.txt | xargs -P 1 -d '\n' -I {} echo "{}" | wc -l
time while read -r p || [ -n "$p" ]; do echo "$p"; done < input.txt | wc -l
ここで2番目の解決策はたくさん急いで。なぜそんなことですか?
私はこれがファイルの行数を数える正しい方法ではないことを知っています。この質問はただ私の観察的関心からのものです。
答え1
はい、予想通り、これは実際にxargs -P 1 -d '\n' -I {} echo "{}"
プロセスを分岐し、各入力行に対して親プロセスで終了するのを待っている間、子プロセスから独立したプロセスを実行する基本コマンドと同じです。xargs -rd '\n' -n1
echo
echo
したがって、これは同じシェルプロセスで非効率的な組み込み機能とすべての組み込み機能を使用するよりもread
はるかに多くの作業です。echo
xargs
xargs
(少なくとも一部の設定と最新バージョンでは)プロセスを分岐せずに内部でbusyboxを呼び出すGNUの代わりにbusyboxを使用すると、ループよりはるかに高速ですecho
。bash
より関連性の高い比較のために、以下を比較する必要があります。
tr -d '\r' | xargs -rd'\n' -n1
そして
tr -d '\r' |
while IFS= read -r line || [ -n "$line" ]; do
/bin/echo "$line"
done
ほとんどの時間がプロセスを分岐して独立して実行するのに費やされるため、同様の結果が得られますecho
。
ここでは、出力seq 3e7
と測定pv -al > /dev/null
(a
1秒あたりの平均線で測定されたスループット)に関する解決策を得ました。l
- busybox xargsは1.12M/sです。
- 70k/sのエコーを内蔵したbashループ
- GNU xargsは860/sです。
- /bin/echo を使用した bash ループの場合、850/s