組み込みLinuxのパイプラインコマンドパフォーマンス

組み込みLinuxのパイプラインコマンドパフォーマンス

最近、私たちは開発中のデバイスに統合するためにソフトウェアソリューションを購入しました。必要に応じて変更し、適用する必要があります。だから今日、私はいくつかのコードを見て、変更する必要があるものを確認し、いくつかの点について考え始めました。

いくつかのスクリプトを見ている間、目に見えるいくつかの行が見つかりました。たとえば、次のようになります。

cat file | grep ^field | head -n1 | sed 's/:/ /' | awk '{print $1}'

1回の呼び出しですべてを簡単にできる場合、これは少し愚かなようですawk。おそらく:

awk -F':' '/^field/ {print $1; exit}' file

後で私はこの問題に興味を持ち始め、同様の状況をたくさん見つけました。一部は初期化中に実行されるため、気にしません。一方、他の人は頻繁に呼び出されます。

これは、より少ないリソースで実行できるタスクを実行するためにどこでもスクリプト生成プロセスを持つことができることを意味します。さて、実際に気になり始めました。パイプが多すぎると、どの時点でパフォーマンスが低下し始めますか?特に「管路「選ぶ。

私は実際のPCよりもリソースがはるかに少ないプラットフォームで組み込みLinuxを実行していることに注意してください。質問の目的に応じて、それは重要ではないかもしれません。

答え1

時には物事を分析する方が簡単です。

サンプル入力ファイルを作成しました。

aaaaa:bbbbb:ccccc
aaaaa:bbbbb:ccccc
aaaaa:bbbbb:ccccc
aaaaa:bbbbb:ccccc
field:bbbbb:ccccc
aaaaa:bbbbb:ccccc
aaaaa:bbbbb:ccccc
aaaaa:bbbbb:ccccc
aaaaa:bbbbb:ccccc

シェルスクリプト 'a.sh':

#!/bin/bash
for i in `seq 1 1000`; do
        cat test.dat | grep ^field | head -n1 | sed 's/:/ /' | awk '{print $1}' >/dev/null
done

シェルスクリプト 'b.sh':

#!/bin/bash
for i in `seq 1 1000`; do
        awk -F':' '/^field/ {print $1; exit}' test.dat >/dev/null
done

はじめに:

time ./a.sh
real    0m10.253s
user    0m5.526s
sys 0m8.668s

time ./b.sh
real    0m3.274s
user    0m1.288s
sys 0m1.783s

(これは私が愛している2008 MacBook、2.4 GHz Intel Core 2 Duoで行われました。)

あなたのバージョンが数倍速いことは明らかです。しかし、これは1000通貨の時間です。このシェルコードが実行される頻度によっては、数ミリ秒しか節約できません。

答え2

パフォーマンスは複雑です。確かに知ることができる唯一の方法は、実際の負荷を持つ実際のシステムをベンチマークすることです。

複数のユーティリティのためにパイプを実行するには確かにコストがかかります。このコストは文字列操作と比較して非常に高いです。ただし、データ量が十分に大きい場合は、特別なツールがタスクをより迅速に完了でき、並列データ処理が可能になり、パイプラインソリューションが高速になる可能性があります(マシンがマルチコアで有用なデータが十分にある場合)。同時に実行して価値のあるものにすることができる処理です。ただし、データ量が小さい場合、プログラムの起動コストは支配的です。主な要因が変わる時点は、システムと使用シナリオによって大きく異なります。

一般に、ツールが一般的であるほど、速度は遅くなります。したがって、できることgrepがある場合は通常行うことができますが、それほど高速で遅くすることはできません。これは単なる経験の法則です。参照すると、awkまたはsedが他のツールよりも優れている特定の実装と特定のワークロードを見つけることができます。データ量は、違いを観察するのに十分な大きさでなければなりません。headsedawk

データ量が小さい場合、プロセスの開始回数は主要コストです。一般に、ツールがより一般的であるほど、起動速度は遅くなります。複数のツールを実行すると、より多くのコードをメモリにロードする必要があるため、パフォーマンスコストが発生します。ただし、すべてのツールが1つの実行可能ファイルにグループ化されているBusyBoxを使用すると、これらの側面は最小限に抑えられます。

から始まる

cat file | grep ^field | head -n1 | sed 's/:/ /' | awk '{print $1}'

呼び出しはcat役に立たず、パフォーマンスには役立ちません。データ量が非常に多い場合は、を使用することにgrep ^field | head -n1 | sed 's/:/ /' いくつかの利点があるかもしれませんが、ほとんどの場合

<file sed -n '/^field/ { s/:/ /p; q; }'

複数のプロセスを待つ必要がないため、より高速です。

awk呼び出しはここではまったく必要ありません。前にコロンがない場合、コマンドは次のようになります。

<file sed -n '/^field/ { s/:.*//p; q; }'

またはgrep有利だと判断した場合

<file grep '^field' | sed -e 's/:.*//' -e 'q'

前にコロンがある場合は、s/^::*//コマンドの先頭に追加しますsed

関連情報