長い質問に申し訳ありませんが、Jon Skeetの参考情報がありますので、若干価値があるかもしれません。要するにInterlocked.Read/Interlocked.Exchangeは.NETよりMonoの方がずっと遅いですか?
:Interlocked.Read
/Interlocked.Exchange
は、.NETフレームワークで実行中よりもモノラルフレームワークで実行しながら、はるかに遅い実行するように見えます。なぜ私は知りたいのですか。長期で
:次に
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にジョンスキートの答えを読んで、私はこれを作った:私は、32ビット・プラットフォームのためのスレッドセーフなダブルを望んでいたので、私は、この構造体を作っ
構造体:
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フレームワーク使用して、この結果を得た:
とMonoフレームワーク使用して、この結果:私は両方のテストを実行してきました
を同じマシン上で複数回(の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フレームワークは一貫Exchange
とRead
の両方で〜2.5秒を返します。 Monoフレームワークは〜5.1秒を返します。
"このテストは本当に便利ではありません"から始めよう:現在のバージョンのパフォーマンスを比較するために、Windowsでは.Net 4.0 64bit、LinuxではMonoを実行する。 – skolima
インターロックされたメソッドが遅いかどうかは実際にはわかりませんが、インターフェイスのディスパッチもそうです。結論を導き出す前に、できるだけ多くの一般化を取り除くことをお勧めします(つまり、インターロックされたメソッドをループ内に置くだけです)。 –
@RolfBjarneKvinge - 簡単なテストと結果で質問を更新しました。 – ken