我写的小测试程序,并很惊讶为什么lock {}
解决方案的性能比无锁但[ThreadStatic]
属性在静态变量更快。.NET:ThreadStatic vs lock {}。为什么ThreadStaticAttribute会降低性能?
[ThreadStatic]片段:
[ThreadStatic]
private static long ms_Acc;
public static void RunTest()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int one = 1;
for (int i = 0; i < 100 * 1000 * 1000; ++i) {
ms_Acc += one;
ms_Acc /= one;
}
stopwatch.Stop();
Console.WriteLine("Time taken: {0}", stopwatch.Elapsed.TotalSeconds);
}
锁{}片段:
private static long ms_Acc;
private static object ms_Lock = new object();
public static void RunTest()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int one = 1;
for (int i = 0; i < 100 * 1000 * 1000; ++i) {
lock (ms_Lock) {
ms_Acc += one;
ms_Acc /= one;
}
}
stopwatch.Stop();
Console.WriteLine("Time taken: {0}", stopwatch.Elapsed.TotalSeconds);
}
在我的机器第一片断接受4.2秒;第二 - 3.2秒,这是1秒快。没有ThreadStatic和锁 - 1.2秒。
我很好奇,为什么在这个简单的例子[ThreadStatic]
属性增加了这么多的程序执行时间?
UPDATE:我感到非常抱歉,但这些结果是为DEBUG
构建。对于RELEASE
我有一个完全不同的数字:(1.2; 2.4; 1.2)。对于DEBUG
号码分别是(4.2; 3.2; 1.2)。
因此,对于RELEASE
构建似乎没有[ThreadStatic]
性能损失。
那不是我看到我的四核。如果我在任何Cpu上编译发布,我会在第一个片段中获得0.81s,在第二个片段中获得4.5s。没有线程安全的平凡情况需要0.46s。 – FuleSnabel
你说得对。我从'Debug'切换到'Release'模式,并得到了类似于你的结果。 – Roman
它可以帮助阅读反汇编的代码,以了解为什么你会得到惊人的结果。 – FuleSnabel