C#のクロージャは、生成されたilでコードの膨張を引き起こしますか?クロージャ変数を持つラムダは、ラムダのコンテキストを格納できるオブジェクトファイルに非表示のクラスを生成するため、避けるように言われました。クローズドオーバー変数を持つすべてのラムダのクラス。これは本当ですか?または、コンパイラはタプルや内部クラスなどの既存のクラスを再利用しますか?
2 に答える
追加のクラスは、必要な場合にのみ生成されます-以外の変数をキャプチャする場合this
。ただし、ほとんどの場合、これは実際にはコードの膨張ではありません。デリゲートを必要な方法で機能させるために必要です。
場合によっては、より効率的なコードを自分で作成することもできますが、通常、同じ効果を持つデリゲートを取得するには、コンパイラーが生成するものと同様のコードを作成することになりますが、かなり読みにくくなります。
ほとんどの場合、この種の「肥大化」について心配する必要はありません。最初はパフォーマンスのマイクロ最適化を避け、読みやすさを最適化し、推測するのではなくパフォーマンスを測定します。次に、本当に重要なコードのビットを攻撃し、それが価値があることを証明したときに、パフォーマンスのために読みやすさを少し犠牲にすることができます。
(最新のC#を記述し、ラムダ式を意図的に回避することは、片方の手を後ろで縛ってコーディングしようとするようなものです。アドバイスをする人がクロージャの「膨張」について心配している場合は、状態を示すことで心臓発作を起こすことができます。 C#5で非同期/待機用に生成されたマシン...)
ええそれはそうです。
変数を追跡するクラスが存在する必要があります。または内部クラスは、考えられるすべてのTuple
コードパスに対してこれを実行できるわけではないため、このようなステートマシンは、特にラムダ/クロージャごとにILで生成する必要があります。
これがアプリケーションの問題であるかどうかは、判断する必要があります。