他の人が言っているように、この種の怠惰な初期化が必要な場合は、はるかに大きな問題が発生します。
しかしとにかく、この質問を自分でどのように処理する必要があるかを示すためだけに、仮定を立てる前に測定してください。
以下のプログラム(ayendeに触発された)は、単に新しいオブジェクトを割り当てるLazy()インスタンスの作成と初期化のオーバーヘッドを測定します。
私のマシンでの出力:
Created 583599 objects in 00:00:01.0000117
Created 679939 objects in 00:00:01.0039926
Created 688751 objects in 00:00:01.0000013
Created 678244 objects in 00:00:01.0000018
Created 682506 objects in 00:00:01.0000018
Created and initialized 516400 lazy objects in 00:00:01.0000018
Created and initialized 526585 lazy objects in 00:00:01.0000049
Created and initialized 519425 lazy objects in 00:00:01.0000018
Created and initialized 514477 lazy objects in 00:00:01.0000022
Created and initialized 523544 lazy objects in 00:00:01.0005176
Performance loss: 21,5091944284387 %
多くの場合、パフォーマンスの問題は目前の状況に非常に固有であるため、これから一般的な結論を導き出さないでください。
しかし、ご覧のとおり、オブジェクトをインスタンス化するオーバーヘッドは、インスタンス化を遅らせるLazy
ことが役立つ(つまり、高価で、構築されたオブジェクトがそうでない可能性が高い)状況で通常発生するnew
ことを考えると、比較的小さいです。Lazy
実際に必要)
class Program
{
static void Main(string[] args)
{
var sequence = Enumerable.Range(1, 5);
var q1 = from s in sequence
select GenerateSimpleObjects();
var q2 = from s in sequence
select GenerateAndInitializeLazies();
var m1 = q1.Average();
var m2 = q2.Average();
Console.WriteLine("Performance loss: {0} %", 100 - 100 * m2/m1);
}
static void GenerateSimpleObjects()
{
var sp = Stopwatch.StartNew();
int i = 0;
while (sp.ElapsedMilliseconds < 1000)
{
new object();
i++;
}
sp.Stop();
Console.WriteLine("Created {0} objects in {1}", i, sp.Elapsed);
}
static void GenerateAndInitializeLazies()
{
var sp = Stopwatch.StartNew();
int i = 0;
while (sp.ElapsedMilliseconds < 1000)
{
var l = new Lazy<object>(() => new object());
var o = l.Value;
i++;
}
sp.Stop();
Console.WriteLine("Created and initialized {0} lazy objects in {1}", i, sp.Elapsed);
}
}