17

これら 2 つの類似したコマンドの違いを理解しようとしています。

aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
  • <()が必要なのはわかっていますが#!/bin/bash、それによって遅くなりますか?
  • それらは同じ量のサブシェルを作成しますか?
  • 同じ量bashまたはshプロセスが必要ですか?

最高のパフォーマンスでコマンドを使用したいと考えています。

4

4 に答える 4

8
  1. いいえ。bash は非 POSIX モードの方が高速です。
  2. 場合によります。これは、実装固有およびプラットフォーム固有の詳細です。
    • Bash では、どちらも同じ数のプロセスを必要とします。が有効になっていない場合lastpipeは、各パイプライン要素のプロセスと、いずれかの置換のサブシェルと親プロセスがあります。
    • Bash では、lastpipeが有効になっている場合、パイプラインの最後の要素はexecどちらの場合も fork せずに、同じ数のプロセスを必要とします。
    • ksh93 では、この場合、どちらも同じ数のプロセスを必要としますが、最後のパイプライン要素が組み込みの場合、コマンド置換の親プロセスで実行されるため、さらに高速になります。
    • Bash と ksh93 の両方で、シェルが をサポートしないシステムでコンパイルされている場合、シェルは/dev/fd/*代わりにプロセス置換用の名前付きパイプを作成します。これはパフォーマンスに影響を与える可能性があります。
  3. 前の弾丸はおそらくここに行くべきです。「サブシェル」は必ずしも別のプロセスを意味するわけではありませんが、ほとんどすべてのシェルではそうです (それ$(<...)をサポートする Bash 以外のすべてを除いて)。mksh と ksh93 には${ ;}スタイルのコマンド置換もありますが、各シェルはこれを異なる方法で実装します。ksh93 では、高速化される場合とされない場合があります。mkshでは、おそらくそうではありません。mksh はプロセス置換をサポートしておらず、zsh はサポートしていない (そしてシミュレートする方法がない)BASHPIDため、調べていません。

コマンド置換について、Bash のプロセス置換よりも本質的に速いものはありませんが、そこでは 1 行しか読み取っていないためhead、冗長です。read余談ですが、常にhead -n ...---1は移植性がありません。また、シェルに入力をマングルさせたい場合を除き、readwithout を使用しないでください。-r

于 2013-03-14T19:03:44.130 に答える
3

ここでパフォーマンスを向上させる最善の方法は、フォークとパイプをできるだけ取り除くことです。

すべての意図と目的において、前述のパフォーマンスの問題について心配する必要はありません。実行時間の 99% は、プロセス置換とコマンド置換の違いではなく、特定のコマンドによって決定される可能性があります。最適化の第一法則を知っていますか?しないでください。特に移植性を犠牲にしている場合。$(whatever)他のすべてを使用して忘れてください。本当にパフォーマンスが心配なら、対処する必要があるのはコマンド/パイプ/フォークです。そうしないと、目から涙を絞って体重を減らそうとしています.

于 2013-03-14T18:13:17.947 に答える
2

Bash's組み込みの でベンチマークするとtime、最初の形式は 2 番目の形式よりも遅くなります。

あなたはそれを自分でテストすることができます:

bash -c 'time PIPELINE...'

どちらもサブシェルを作成します。最初のケースではシェルがサブシェルの出力を読み取って展開し、2 番目のケースではシェルのread組み込みプロセスがバックグラウンド プロセスから読み取ります。

見る:

于 2013-03-14T17:58:44.187 に答える
1

プロセス置換は、パイプライン/コマンド置換によって作成されたサブシェルをバイパスします。置換構文は FIFO または FD の名前に置き換えられ、その中のコマンドはバックグラウンドで実行されます。置換は、パラメータ展開とコマンド置換と同時に実行されます。

「tee」で使用されるプロセス置換に関する情報も確認してください。

http://mywiki.wooledge.org/ProcessSubstitution

于 2013-03-14T18:27:26.223 に答える