對不起,有一個長期的問題,但有一個喬恩Skeet參考,所以它可能是值得的一些。Interlocked.Read/Interlocked.Exchange在Mono比.NET慢很多?
簡而言之:Interlocked.Read
/Interlocked.Exchange
似乎在單聲道框架比而在.NET框架運行運行的同時執行慢得多。我很想知道爲什麼。
在長:
我想爲32位平臺的線程安全的雙,所以我做了這個結構:
public interface IThreadSafeDouble
{
double Value { get; set; }
}
public struct LockedThreadSafeDouble : IThreadSafeDouble
{
private readonly object Locker;
private double _Value;
public double Value
{
get { lock (Locker) return _Value; }
set { lock (Locker) _Value = value; }
}
public LockedThreadSafeDouble(object init)
: this()
{
Locker = new object();
}
}
然後我讀喬恩斯基特的回答this question,所以我做了這個結構:
public struct InterlockedThreadSafeDouble : IThreadSafeDouble
{
private long _Value;
public double Value
{
get { return BitConverter.Int64BitsToDouble(Interlocked.Read(ref _Value)); }
set { Interlocked.Exchange(ref _Value, BitConverter.DoubleToInt64Bits(value)); }
}
}
然後我寫了這個測試:
private static TimeSpan ThreadSafeDoubleTest2(IThreadSafeDouble dbl)
{
var incrementTarg = 10000000;
var sw = new Stopwatch();
sw.Start();
for (var i = 0; i < incrementTarg; i++, dbl.Value++);
sw.Stop();
return sw.Elapsed;
}
private static void ThreadSafeTest()
{
var interlockedDbl = new InterlockedThreadSafeDouble();
var interlockedTim = ThreadSafeDoubleTest2(interlockedDbl);
var lockedDbl = new LockedThreadSafeDouble(true);
var lockedTim = ThreadSafeDoubleTest2(lockedDbl);
System.Console.WriteLine("Interlocked Time: " + interlockedTim);
System.Console.WriteLine("Locked Time: " + lockedTim);
}
public static void Main(string[] args)
{
for (var i = 0; i < 5; i++)
{
System.Console.WriteLine("Test #" + (i + 1));
ThreadSafeTest();
}
System.Console.WriteLine("Done testing.");
System.Console.ReadLine();
}
我使用.NET框架得到了這個結果:
並採用單框架這樣的結果:
我已經跑了兩個測試在同一臺機器上多次(Windows XP中)結果是一致的。我很想知道爲什麼Interlocked.Read/Interlocked.Exchange似乎在Mono框架上表現得太慢了。
更新:
我寫了下面,簡單的測試:
long val = 1;
var sw = new Stopwatch();
sw.Start();
for (var i = 0; i < 100000000; i++) {
Interlocked.Exchange(ref val, 2);
// Interlocked.Read(ref val);
}
sw.Stop();
System.Console.WriteLine("Time: " + sw.Elapsed);
NET框架始終返回〜2.5秒既Exchange
和Read
。 Mono框架返回〜5.1秒。
我從「這個測試不是很有用」開始:在Windows上運行.NET 4.0 64位,在Linux上運行Mono來比較當前版本的性能。 – skolima 2012-02-07 16:15:34
您實際上並不知道它是否是聯鎖方法較慢,它可能也是接口調度。我建議在得出任何結論之前儘可能多地去除泛化(即將聯鎖方法放在循環中)。 – 2012-02-07 21:18:58
@RolfBjarneKvinge - 我用一個更簡單的測試和結果更新了我的問題。 – ken 2012-02-08 21:44:32