ゼファーネットのロゴ

Bash パイプラインのメンタル モデルは間違っていますか?

日付:

[マイケル・リンチ]は奇妙な状況に遭遇した。 彼のプログラムのコンパイルと実行に 10 倍近い時間がかかったのはなぜですか 速いです プログラムを単独で実行するだけではなく? [Michael] は、プログラミング プロジェクトのベンチマークを行っているときにこの問題に遭遇し、再現性と分析のために本質的な部分まで切り詰めたところ、この問題が bash パイプラインの動作に関する間違ったメンタル モデルを浮き彫りにしていることを発見しました。

状況は次のとおりです。 [マイケル] の簡略化されたプログラムが最初に行うことは、タイマーを開始することです。次に、単純にからいくつかのバイトを読み取ってカウントします。 stdin、それが起こるまでにかかった時間を出力します。以下の方法でテストプログラムを実行すると、約 13 マイクロ秒かかります。

$ echo '00010203040506070809' | xxd -r -p | zig build run -Doptimize=ReleaseFast
bytes: 10
execution time: 13.549µs

(コンパイル済みの) プログラムを直接実行すると、実行時間は 162 マイクロ秒に増加します。

$ echo '00010203040506070809' | xxd -r -p | ./zig-out/bin/count-bytes
bytes: 10
execution time: 162.195µs

繰り返しますが、両者の唯一の違いは、 zig build run & ./zig-out/bin/count-bytes つまり、最初にコードをコンパイルし、すぐに実行します。 2 つ目は、コンパイルされたプログラムを単純に実行します。

追加のコンパイル手順を追加するにはどうすればよいですか 減少 実行時間は? bash パイプラインがどのように機能するかについての [マイケル] のメンタル モデルは間違っていたことが判明しましたが、彼は素晴らしい仕事をしています。 実際にどのように機能するのか、そしてそれがなぜ奇妙な動作を引き起こしたのかを説明する 彼は見ていた。

つまり、bash パイプラインのコマンドは順番に起動されません。これらはすべて同時に起動され、並行して実行されます。これは、直接実行すると、[Michael] のバイトカウンター プログラムがすぐに起動することを意味します。その後、約 150 マイクロ秒間、何もせずに待機しました。 echo '00010203040506070809' | xxd -r -p パイプラインの一部が、プログラムが読み取るデータの配信に取り掛かりました。ここで、コンパイル済みバージョンを実行するときに余分な実行時間が発生します。

では、なぜ最初にコンパイルすると実行速度が速くなるのでしょうか?基本的な理由は同じです。 zig build run コマンドが開始されると、最初にプログラムのコンパイルに少し時間がかかります。その後、コンパイルされたプログラムが実際に起動される (そしてその実行タイマーが開始される) とき、bash パイプラインからの入力データはすでに準備ができています。したがって、新たにコンパイルされたプログラムは、パイプラインの以前のデータが利用可能になるまで待機することがないため、より短い時間で実行されます。

これは、bash パイプラインが実際に内部でどのように機能するかを示す興味深いものであり、[Micheal] が全体の行程と説明に込めた詳細に満足しています。遅かれ早かれ、このような詳細が明らかになり、発見したユーザーのように眉をひそめる人もいます。 ssh コマンドのスペースに関する厄介な特殊ケース.

スポット画像

最新のインテリジェンス

スポット画像