これら 2 つの類似したコマンドの違いを理解しようとしています。
aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
<()が必要なのはわかっていますが#!/bin/bash、それによって遅くなりますか?- それらは同じ量のサブシェルを作成しますか?
- 同じ量
bashまたはshプロセスが必要ですか?
最高のパフォーマンスでコマンドを使用したいと考えています。
これら 2 つの類似したコマンドの違いを理解しようとしています。
aa=$(foo | bar | head -1)
read aa < <(foo | bar | head -1)
<()が必要なのはわかっていますが#!/bin/bash、それによって遅くなりますか?bashまたはshプロセスが必要ですか?最高のパフォーマンスでコマンドを使用したいと考えています。
lastpipeは、各パイプライン要素のプロセスと、いずれかの置換のサブシェルと親プロセスがあります。lastpipeが有効になっている場合、パイプラインの最後の要素はexecどちらの場合も fork せずに、同じ数のプロセスを必要とします。/dev/fd/*代わりにプロセス置換用の名前付きパイプを作成します。これはパフォーマンスに影響を与える可能性があります。$(<...)をサポートする Bash 以外のすべてを除いて)。mksh と ksh93 には${ ;}スタイルのコマンド置換もありますが、各シェルはこれを異なる方法で実装します。ksh93 では、高速化される場合とされない場合があります。mkshでは、おそらくそうではありません。mksh はプロセス置換をサポートしておらず、zsh はサポートしていない (そしてシミュレートする方法がない)BASHPIDため、調べていません。コマンド置換について、Bash のプロセス置換よりも本質的に速いものはありませんが、そこでは 1 行しか読み取っていないためhead、冗長です。read余談ですが、常にhead -n ...---1は移植性がありません。また、シェルに入力をマングルさせたい場合を除き、readwithout を使用しないでください。-r
ここでパフォーマンスを向上させる最善の方法は、フォークとパイプをできるだけ取り除くことです。
すべての意図と目的において、前述のパフォーマンスの問題について心配する必要はありません。実行時間の 99% は、プロセス置換とコマンド置換の違いではなく、特定のコマンドによって決定される可能性があります。最適化の第一法則を知っていますか?しないでください。特に移植性を犠牲にしている場合。$(whatever)他のすべてを使用して忘れてください。本当にパフォーマンスが心配なら、対処する必要があるのはコマンド/パイプ/フォークです。そうしないと、目から涙を絞って体重を減らそうとしています.
Bash's組み込みの でベンチマークするとtime、最初の形式は 2 番目の形式よりも遅くなります。
あなたはそれを自分でテストすることができます:
bash -c 'time PIPELINE...'
どちらもサブシェルを作成します。最初のケースではシェルがサブシェルの出力を読み取って展開し、2 番目のケースではシェルのread組み込みプロセスがバックグラウンド プロセスから読み取ります。
見る:
プロセス置換は、パイプライン/コマンド置換によって作成されたサブシェルをバイパスします。置換構文は FIFO または FD の名前に置き換えられ、その中のコマンドはバックグラウンドで実行されます。置換は、パラメータ展開とコマンド置換と同時に実行されます。
「tee」で使用されるプロセス置換に関する情報も確認してください。