
次の比較については、専門家のアドバイスが必要です。
ループを使用するコードスニペット:
for file in `cat large_file_list`
do
gzip -d $file
done
単純な拡張を使用したコードスニペット:
gzip -d `cat large_file_list`
どちらが速いですか?大規模なデータセットで動作する必要があります。
答え1
複雑
以下は時々有効です。
gzip -d `cat large_file_list`
3つの問題は(bash
ほとんどのBourne様シェルでは)次のようなものです。
ファイル名にスペースタブまたは改行文字が含まれている場合は失敗します(
$IFS
変更されていないと仮定)。その理由は殻のためです。噴射。ファイル名にグローバルアクティブ文字が含まれていても失敗することがあります。シェルが適用されるからです。パス名拡張ファイルリストに
ファイル名が
-
(POSIXLY_CORRECT=1
最初のファイルにのみ適用される場合)で始まるか、ファイル名が-
。1つのコマンドラインに入ることができないほどファイル名が多すぎると失敗します。
以下のコードは上記のコードと同じ問題があります(4番目のコードを除く)。
for file in `cat large_file_list`
do
gzip -d $file
done
安定したソリューション
1 行に 1 つのファイル名のみがあり、名前付きファイルがlarge_file_list
その-
中になく GNU システムを使用している場合は、次のようにします。
xargs -rd'\n' gzip -d -- <large_file_list
-d'\n'
xargs
各入力行を別々のファイル名として処理するように指示します。
-r
xargs
入力ファイルが空の場合は、コマンドを実行しないように指示します。
--
gzip
次の引数は、で始まってもオプションと見なされないことを示します-
。個々のファイルは呼び出されるの-
ではなく、引き続き考慮されます。-
-
xargs
各コマンドラインに複数のファイル名が割り当てられますが、その数はコマンドライン制限を超えません。これにより、プロセスを開始する必要がある回数が減り、gzip
速度が速くなります。また安全です。ファイル名も保護されます。噴射そしてパス名拡張。
答え2
これが重要かは疑問だ。
これは、リストファイルにどのくらいのファイルがリストされているのかわからないため、ループを使用し、ファイル名にスペースが含まれているか(通常)知らないためです。非常に長い引数リストを生成するコマンド置換を実行すると、結果リストの長さが長すぎると、「引数リストが大きすぎる」エラーが発生する可能性があります。
私のループは次のとおりです
while IFS= read -r name; do
gunzip "$name"
done <file.list
また、gunzip
コマンドの後にデータ処理用のコマンドを挿入することもできます。実際には、データの実際の内容とそれを実行する必要がある操作によっては、ファイルに保存せずに処理することができます。
while IFS= read -r name; do
zcat "$name" | process_data
done <file.list
(process_data
標準入力から圧縮されていないデータを読み取るパイプはどこにあります)
データ処理が解凍より長くかかる場合、ループがより効率的であるかどうかに関する質問は不適切です。
理想的には、私はファイル名のリストを扱うことなく、次のファイル名のグローブパターンを使用したいと思います。
for name in ./*.gz; do
# processing of "$name" here
done
./*.gz
問題のファイルと一致するいくつかのパターンがあります。これは、ファイルの数やファイル名に使用される文字(改行やその他の空白文字を含めたり、ダッシュで始めることができるなど)に依存しません。
関連:
答え3
2つのうち、すべてのファイルを1回の呼び出しで転送する方がgzip
高速です。まさに一度だけ始めればいいからですgzip
。 (つまり、コマンドがまったく機能する場合は、注意事項の他の答えを参照してください。)
しかし、私がみんなに思い出させたいのは最適化の黄金率:この作業を早期に行わないでください。
問題があることがわかるまで、この種の作業を最適化しないでください。
このプロセスには時間がかかりますか?もちろん、大容量ファイルを解凍すると、おそらくそうでしょう。
測定する。実際、それが確かに知っている最良の方法です。
結果は直接目で確認するか(またはストップウォッチを使用して)、次に適用されます。あなたの状況インターネットのランダムな答えはおそらくそうではありません。これら2つのバリエーションをスクリプトに入れて実行します
time script1.sh
。time script2.sh
(空のアーカイブリストを使用してオーバーヘッドの絶対量を測定します。)
答え4
あなたのディスクはどれくらい速いですか?
これはCPUをすべて使用する必要があります。
parallel -X gzip -d :::: large_file_list
したがって、制限はディスク速度になる可能性があります。
以下を調整してみることができます-j
。
parallel -j50% -X gzip -d :::: large_file_list
これは、前のコマンドのようにタスクの半分を並列に実行し、ディスクへの負担を軽減し、ディスクによっては速度が速くなる可能性があります。