これら 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
は移植性がありません。また、シェルに入力をマングルさせたい場合を除き、read
without を使用しないでください。-r
ここでパフォーマンスを向上させる最善の方法は、フォークとパイプをできるだけ取り除くことです。
すべての意図と目的において、前述のパフォーマンスの問題について心配する必要はありません。実行時間の 99% は、プロセス置換とコマンド置換の違いではなく、特定のコマンドによって決定される可能性があります。最適化の第一法則を知っていますか?しないでください。特に移植性を犠牲にしている場合。$(whatever)
他のすべてを使用して忘れてください。本当にパフォーマンスが心配なら、対処する必要があるのはコマンド/パイプ/フォークです。そうしないと、目から涙を絞って体重を減らそうとしています.
Bash's
組み込みの でベンチマークするとtime
、最初の形式は 2 番目の形式よりも遅くなります。
あなたはそれを自分でテストすることができます:
bash -c 'time PIPELINE...'
どちらもサブシェルを作成します。最初のケースではシェルがサブシェルの出力を読み取って展開し、2 番目のケースではシェルのread
組み込みプロセスがバックグラウンド プロセスから読み取ります。
見る:
プロセス置換は、パイプライン/コマンド置換によって作成されたサブシェルをバイパスします。置換構文は FIFO または FD の名前に置き換えられ、その中のコマンドはバックグラウンドで実行されます。置換は、パラメータ展開とコマンド置換と同時に実行されます。
「tee」で使用されるプロセス置換に関する情報も確認してください。