Nur aus Neugier habe ich ein Programm gemacht, um die Leistung von InterLocked vs Lock in .Net zu testen. Es stellt sich heraus, Interlocked Version ist viel langsamer als Locked-Version, kann jemand bitte darauf hinweisen, wenn ich hier einige Details vermisse. Nach meinem Verständnis sollte Interlocked viel besser als Sperre durchführen.Warum ist Interlocked langsamer als Sperre?
public class TestB
{
private static readonly object _objLocker = new object();
private long _shared;
public void IncrLocked()
{
lock (_objLocker)
{
_shared++;
}
}
public void IncrInterLocked()
{
Interlocked.Increment(ref _shared);
}
public long GetValue()
{
return _shared;
}
}
class TestsCopy
{
private static TestB _testB = new TestB();
static void Main(string[] args)
{
int numofthreads = 100;
TestInterLocked(numofthreads);
TestLocked(numofthreads);
Console.ReadLine();
}
private static void TestInterLocked(int numofthreads)
{
Thread[] threads = new Thread[numofthreads];
for (int i = 0; i < numofthreads; i++)
{
Thread t = new Thread(StartTestInterLocked);
threads[i] = t;
t.Start();
}
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < threads.Length; i++)
{
threads[i].Join();
}
sw.Stop();
Console.WriteLine($"Interlocked finished in : {sw.ElapsedMilliseconds}, value = {_testB.GetValue()}");
}
private static void TestLocked(int numofthreads)
{
Thread[] threads = new Thread[numofthreads];
for (int i = 0; i < numofthreads; i++)
{
Thread t = new Thread(StartTestLocked);
threads[i] = t;
t.Start();
}
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < threads.Length; i++)
{
threads[i].Join();
}
sw.Stop();
Console.WriteLine($"Locked finished in : {sw.ElapsedMilliseconds}, value = {_testB.GetValue()}");
}
private static void StartTestInterLocked()
{
int counter = 10000000;
for (int i = 0; i < counter; i++)
{
_testB.IncrInterLocked();
}
}
private static void StartTestLocked()
{
int counter = 10000000;
for (int i = 0; i < counter; i++)
{
_testB.IncrLocked();
}
}
Die Ausgabe des Programms ist ...
Interlocked finished in : 76909 ms, value = 1000000000
Locked finished in : 44215 ms, value = 2000000000
Sie testen nur den Fall, in dem es hier extrem viele gleichzeitige Zugriffe gibt. Für einen faireren Test sollten Sie auch testen, was schneller ist, wenn kein gleichzeitiger Zugriff oder ein normaler Wert vorhanden ist. – hvd
Ich denke, Ihre Messung ist fehlerhaft. Sie starten alle Threads, bevor Sie die Stoppuhr starten. Viele, wenn nicht die meisten der Threads werden abgeschlossen sein, bevor die Messung beginnt. –