【发布时间】:2013-04-30 02:29:25
【问题描述】:
我想知道即使代码从未执行过,一段锁定的代码如何会减慢我的代码速度。下面是一个例子:
public void Test_PerformanceUnit()
{
Stopwatch sw = new Stopwatch();
sw.Start();
Random r = new Random();
for (int i = 0; i < 10000; i++)
{
testRand(r);
}
sw.Stop();
Console.WriteLine(sw.ElapsedTicks);
}
public object testRand(Random r)
{
if (r.Next(1) > 10)
{
lock(this) {
return null;
}
}
return r;
}
这段代码在我的机器上运行大约 1300 毫秒。如果我们移除锁块(但保留它的主体),我们得到 750 毫秒。几乎是两倍,即使代码从未运行过!
当然,这段代码什么也不做。我在一个类中添加一些惰性初始化时注意到了这一点,代码检查对象是否已初始化,如果没有初始化它。问题是初始化被锁定并且即使在第一次调用之后也会减慢一切。
我的问题是:
- 为什么会这样?
- 如何避免减速
【问题讨论】:
-
除非你打算大量使用
lock- 我真的不会担心。 -
我得到了类似的结果,但一个刻度是 100 nano-秒。两次运行都应该花费大约 0 毫秒(即,如果您打印
sw.ElapseMilliseconds。)这种“减速”(大约 0.00006 秒)可能是因为lock包含一个try/finally块,该块可能正在设置该方法时叫做。尝试将testRand的内容放入循环本身;那时你会看到几乎没有减速。 -
Similar topic here。结果应该几乎相同。
-
我已将此追踪到
try{}finally{}声明。如果你使用它(即使是空的,没有嵌入代码)也会出现同样的减速。lock语句实现try{}finally{}。 -
另一个问题有一些启发性的答案:stackoverflow.com/questions/6029804/…
标签: c# performance