正如其他人所说,如果您需要这种惰性初始化,您会遇到更大的问题。
但无论如何,只是为了说明你应该如何自己处理这个问题:在做出假设之前进行测量。
下面的程序(受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);
}
}
什么让你“相当肯定”有一个性能损失?你测过它了吗? – jeroenh 2011-04-23 19:06:22
没有什么比使用OOP语言进行100个静态类的程序编程...就像在Haskell中做OOP一样;这是一个坏主意。 – alternative 2011-04-23 19:08:37
@jeroenh nop,但我想如果我应该在所有的静态类使用Lazys – Pacerier 2011-04-23 19:09:01