正如其他人所说,如果您需要这种延迟初始化,您将面临更大的问题。
但无论如何,只是为了展示你应该如何自己处理这个问题:在做出假设之前测量。
下面的程序(受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);
}
}