我想知道一段锁定代码如何减慢我的代码,即使代码从未执行过.以下是一个示例:
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;
}
Run Code Online (Sandbox Code Playgroud)
这段代码在我的机器上运行〜1300ms.如果我们移除锁定块(但保持其身体),我们得到750毫秒.几乎是双倍,即使代码永远不会运行!
当然这段代码什么也没做.我注意到它在一个类中添加一些延迟初始化,其中代码检查对象是否已初始化,如果没有初始化它.问题是初始化被锁定并且即使在第一次调用之后也会减慢所有内容.
我的问题是:
Zon*_*nko 10
关于它为什么会发生,它已在评论中讨论过:它是由于try ... finally
生成的初始化所致lock
.
为了避免这种减速,您可以将锁定功能提取到新方法,这样只有在实际调用该方法时才会初始化锁定机制.
我用这个简单的代码尝试了它:
public object testRand(Random r)
{
if (r.Next(1) > 10)
{
return LockingFeature();
}
return r;
}
private object LockingFeature()
{
lock (_lock)
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的时间(在刻度线):
your code, no lock : ~500
your code, with lock : ~1200
my code : ~500
Run Code Online (Sandbox Code Playgroud)
编辑:我的测试代码(运行速度比没有锁的代码慢一点)实际上是静态方法,似乎当代码在"内部"对象中运行时,时间是相同的.我根据这个确定了时间.