GNU並列化が遅すぎます。

GNU並列化が遅すぎます。

grep何百万ものファイルを実行する必要があります。だから私はスピードを上げようとしました。ここで言及されている2つの方法xargs -P -nそしてGNU parallel。私のファイルのサブセット(番号9026)に対してこれを試しましたが、結果は次のとおりです。

  1. を使用するとxargs -P 8 -n 1000非常に高速です:

    $ time find tex -maxdepth 1 -name "*.json" | \
                    xargs -P 8 -n 1000 grep -ohP "'pattern'" > /dev/null
    
    real    0m0.085s
    user    0m0.333s
    sys     0m0.058s
    
  2. parallel非常にゆっくり使用してください。

    $ time find tex -maxdepth 1 -name "*.json" | \
                    parallel -j 8 grep -ohP "'pattern'" > /dev/null
    
    real    0m21.566s
    user    0m22.021s
    sys     0m18.505s
    
  3. 注文でさえ次のxargsより良いですparallel

    $ time find tex -maxdepth 1 -name "*.json" | \
                    xargs grep -ohP 'pattern' > /dev/null
    
    real    0m0.242s
    user    0m0.209s
    sys     0m0.040s
    

xargs -P nすべてのプロセスの出力がインターリーブされるため、私には機能しません。parallelしたがって、このような大きな速度低下を起こすことなく使用したいと思いますparallel

どんなアイデアがありますか?

修正する

  1. フォローするオレ・タンジェの回答、試してみましたがparallel -X、完全性のための結果は次のとおりです。

    $ time find tex -maxdepth 1 -name "*.json" | \
        parallel -X -j 8 grep -ohP "'pattern'" > /dev/null
    
    real    0m0.563s
    user    0m0.583s
    sys     0m0.110s
    
  2. 最速のソリューション:フォローする@casでコメント-H、grepオプション(ファイル名の強制印刷)と並べ替えを試しました。結果は次のとおりです。

    time find tex -maxdepth 1 -name '*.json' -print0 | \
        xargs -0r -P 9 -n 500 grep --line-buffered -oHP 'pattern' | \
        sort -t: -k1 | cut -d: -f2- > /dev/null
    
    real    0m0.144s
    user    0m0.417s
    sys     0m0.095s
    

答え1

努力するparallel -X。コメントに記載されているように、新しいシェルを起動し、各引数をバッファリングするためにファイルを開くオーバーヘッドが原因である可能性があります。

したがって、GNU Parallelはxargsほど高速ではありません。 1ジョブあたりの予想されるオーバーヘッドは10ミリ秒です。 -Xを使用すると、ジョブがより多くのパラメータを処理するほど、このオーバーヘッドは重要になりません。

関連情報