sed
vs.のパフォーマンスtail
、ファイルの最初の行を削除する
TL; DR
中小ファイルの場合、sed
およびtail
(あなたの期待に応じて、または遅い)速い同様に行っています。ただし、大きな入力ファイル(複数のMB)の場合、パフォーマンスの差は大幅に大きくなり(数百MBの範囲のファイルでは1桁)、tail
明らかにパフォーマンスが向上しますsed
。
実験
一般的な準備:
分析するコマンドは次のとおりです。
sed '1d' testfile > /dev/null
tail -n +2 testfile > /dev/null
/dev/null
パフォーマンスのボトルネックとしての端末出力またはファイル書き込みをなくすために、毎回出力をパイピングしていることに注意してください。
RAMディスクをセットアップして、潜在的なボトルネックとしてのディスクI / Oを排除しましょう。私は個人的にtmpfs
マウントされている/tmp
のでtestfile
、この実験のためにそこに置いただけです。
次に、$numoflines
このコマンドを使用して、ランダムな行の長さとランダムなデータを含む指定された量の行を含むランダムなテストファイルを作成します(これは明らかに最適ではなく、約200万行を超えると本当に遅くなりますが、私たちが分析しているもの):
cat /dev/urandom | base64 -w0 | tr 'n' '\n'| head -n "$numoflines" > testfile
ああ、ところで。私のテスト用ラップトップは、Intel i5-6200U CPU上で64ビットのUbuntu 16.04を実行しています。比較のためだけに。
大きなファイルのタイミング:
巨大なセットアップtestfile
:
上記のコマンドを実行して、10 numoflines=10000000
MBの行を含むランダムファイルを生成し、600 MBを少し超えて占有します-それは非常に巨大ですが、次のことができるので、始めましょう。
$ wc -l testfile
10000000 testfile
$ du -h testfile
611M testfile
$ head -n 3 testfile
qOWrzWppWJxx0e59o2uuvkrfjQbzos8Z0RWcCQPMGFPueRKqoy1mpgjHcSgtsRXLrZ8S4CU8w6O6pxkKa3JbJD7QNyiHb4o95TSKkdTBYs8uUOCRKPu6BbvG
NklpTCRzUgZK
O/lcQwmJXl1CGr5vQAbpM7TRNkx6XusYrO
私たちのhugeで時限実行を実行しますtestfile
:
では、まず両方のコマンドを使用して1回だけ実行し、どの程度の大きさで作業しているかを推定しましょう。
$ time sed '1d' testfile > /dev/null
real 0m2.104s
user 0m1.944s
sys 0m0.156s
$ time tail -n +2 testfile > /dev/null
real 0m0.181s
user 0m0.044s
sys 0m0.132s
我々はすでに、大きなファイルのために本当に明確な結果を参照してくださいtail
大きさよりも高速ですsed
。ただし、楽しみのために、また大きな違いをもたらすランダムな副作用がないことを確認するために、100回行ってみましょう。
$ time for i in {1..100}; do sed '1d' testfile > /dev/null; done
real 3m36.756s
user 3m19.756s
sys 0m15.792s
$ time for i in {1..100}; do tail -n +2 testfile > /dev/null; done
real 0m14.573s
user 0m1.876s
sys 0m12.420s
結論は同じままsed
で、大きなファイルの最初の行を削除するには非効率的であり、tail
そこで使用する必要があります。
そして、はい、Bashのループ構造が遅いことはわかっていますが、ここでは比較的少数の反復しか行っておらず、とにかくsed
/ tail
ランタイムに比べて単純なループにかかる時間は重要ではありません。
小さなファイルのタイミング:
小さなセットアップtestfile
:
完全を期すために、kBの範囲に小さな入力ファイルがあるというより一般的なケースを見てみましょう。のようなランダムな入力ファイルを作成しましょうnumoflines=100
:
$ wc -l testfile
100 testfile
$ du -h testfile
8,0K testfile
$ head -n 3 testfile
tYMWxhi7GqV0DjWd
pemd0y3NgfBK4G4ho/
aItY/8crld2tZvsU5ly
私たちの小さなもので時限実行を実行しますtestfile
:
このような小さなファイルのタイミングは経験から数ミリ秒の範囲にあると予想できるため、すぐに1000回の反復を実行してみましょう。
$ time for i in {1..1000}; do sed '1d' testfile > /dev/null; done
real 0m7.811s
user 0m0.412s
sys 0m7.020s
$ time for i in {1..1000}; do tail -n +2 testfile > /dev/null; done
real 0m7.485s
user 0m0.292s
sys 0m6.020s
ご覧のように、タイミングは非常に似ており、解釈したり疑問に思うことはあまりありません。小さいファイルの場合、両方のツールが同様に適しています。
sed
より移植性が高いことです。GNUtail
を使用するUbuntuで正常に動作する「+2」ですtail
が、BSDでは動作しませんtail
。