3

2.2Gbのデータを取得して処理するために、非常に長く複雑なシェルパイプラインを設定しています。現在、処理には45分かかります。パイプラインは、cut、grep、sort、uniq、grep、およびawkコマンドの数です。時間がかかるのはgrepの部分だと思いますが、確認する方法がありません。

パイプライン全体をエンドツーエンドで「プロファイリング」して、どのコンポーネントが最も低速であるか、および最適化できるようにCPUまたはIOバウンドであるかどうかを判断する方法はありますか?

残念ながら、独自の情報を投稿する必要があるため、コマンド全体をここに投稿することはできませんが、htopでチェックアウトするのは次のビットだと思います。

grep -v ^[0-9]
4

3 に答える 3

5

これを行う1つの方法は、パイプラインを徐々に構築し、各加算のタイミングを調整し、方程式から可能な限り多くを取り除くことです(端末やファイルへの出力など)。非常に簡単な例を以下に示します。

pax:~$ time ( cat bigfile >/dev/null )
real 0m4.364s
user 0m0.004s
sys  0m0.300s

pax:~$ time ( cat bigfile | tr 'a' 'b' >/dev/null )
real 0m0.446s
user 0m0.312s
sys  0m0.428s

pax:~$ time ( cat bigfile | tr 'a' 'b' | tail -1000l >/dev/null )
real 0m0.796s
user 0m0.516s
sys  0m0.688s

pax:~$ time ( cat bigfile | tr 'a' 'b' | tail -1000l | sort -u >/dev/null )
real 0m0.892s
user 0m0.556s
sys  0m0.756s

上記のユーザー時間とシステム時間を合計すると、増分の増加は次のようになります。

  • cat;の場合は0.304(0.004 + 0.300)秒
  • tr;の場合は0.436(0.312 + 0.428-0.304)秒
  • tail;の場合は0.464(0.516 + 0.688-0.436-0.304)秒 と
  • 0.108(0.556 + 0.756-0.464-0.436-0.304)秒sort

これは、調べるべき主なものがとであることを私に教えてくれtailますtr

明らかに、これはCPU専用であり、平均化の目的で各ステージで複数の実行を実行する必要がありましたが、これが私が採用する基本的な最初のアプローチです。

それが本当にあなたのものであることが判明した場合、あなたgrepが利用できる他のいくつかのオプションがあります。数字で始まらない行を削除できるコマンドは他にもたくさんありますが、これを行うためのカスタムビルドのコマンドは、(テストされていませんが、アイデアを得る必要があります)のような擬似コードの方が高速である場合があります。

state = echo
lastchar = newline
while not end of file:
    read big chunk from file
    for every char in chunk:
        if lastchar is newline:
            if state is echo and char is non-digit:
                state = skip
            else if state is skip and and char is digit:
                state = echo
        if state is echo:
            output char
        lastchar = char

このようなカスタムのターゲットコードは、特定のケースに最適化できるという理由だけで、汎用の正規表現処理エンジンよりも効率的になる場合があります。それが本当であるかどうかは、この場合、またはその問題のいずれかの場合であるかどうかは、テストする必要があります。私の一番の最適化のマントラは測定です、推測しないでください!

于 2011-10-10T13:10:55.093 に答える
4

さらに実験を重ねた結果、自分で問題を見つけました。grepでのエンコーディングサポートが原因のようです。以下を使用すると、パイプラインがハングしました。

grep -v ^[0-9]

次のようにsedに交換したところ、45秒以内に完成しました!

sed '/^[0-9]/d'
于 2011-10-10T12:53:21.470 に答える
1

これはzshで簡単です:

zsh-4.3.12[sysadmin]% time sleep 3 | sleep 5 | sleep 2
sleep 3  0.01s user 0.03s system 1% cpu 3.182 total
sleep 5  0.01s user 0.01s system 0% cpu 5.105 total
sleep 2  0.00s user 0.05s system 2% cpu 2.121 total
于 2011-10-22T06:47:54.350 に答える