正如其他人所說,如果您需要這種惰性初始化,您會遇到更大的問題。
但無論如何,只是爲了說明你應該如何自己處理這個問題:在做出假設之前進行測量。
下面的程序(受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