ist Queue.Synchronized schneller als mit einem Lock ()?

7

Ich habe eine Warteschlange, in der die Enqueue-Operation von einem Thread ausgeführt wird und die Dequeue-Operation von einem anderen ausgeführt wird. Unnötig zu erwähnen, dass ich dafür einige Thread-Sicherheit implementieren musste.

Ich habe zuerst versucht, eine Sperre für die Warteschlange vor jeder Enqueue / Dequeue zu verwenden, da sie eine bessere Kontrolle für den Sperrmechanismus bietet. Es hat gut funktioniert, aber mein neugieriger Verstand hat mich dazu gebracht, noch mehr zu testen.

Ich habe dann versucht, mit Queue.Synchronized Wrapper alles andere gleich zu halten. Jetzt bin ich mir nicht sicher, ob es wahr ist, aber die Leistung scheint mit diesem Ansatz ein bisschen schneller zu sein.

Glauben Sie, es gibt tatsächlich einen Unterschied in der Leistung zwischen den beiden, oder ich stelle mir nur die Dinge hier vor ..? :)

    
Danish Khan 27.01.2011, 15:20
quelle

3 Antworten

16

Wenn Sie Queue.Synchonized anfordern, erhalten Sie eine SynchronizedQueue , die lock sehr minimal bei Aufrufen von Enqueue und Dequeue in einer inneren Warteschlange verwendet. Daher sollte die Leistung dieselbe sein wie die Verwendung von Queue und die Verwaltung der Sperrung für Enqueue und Dequeue mit Ihrer eigenen lock .

Sie stellen sich tatsächlich Dinge vor - sie sollten gleich sein.

Aktualisieren

Es gibt tatsächlich die Tatsache, dass Sie bei Verwendung von SynchronizedQueue eine indirekte Ebene hinzufügen, da Sie die Wrappermethoden durchlaufen müssen, um zu der inneren Warteschlange zu gelangen, die sie verwaltet. Wenn überhaupt, sollte dies die Dinge nur sehr langsam verlangsamen, da Sie einen zusätzlichen Frame auf dem Stack haben, der für jeden Anruf verwaltet werden muss. Gott weiß, ob das In-Lining dies aufhebt. Was auch immer - es ist minimal .

Update 2

Ich habe das jetzt getestet und wie in meinem vorherigen Update vorhergesagt:

  

"Queue.Synchronized" ist langsamer als "Queue + lock"

Ich habe einen single-threaded-Test durchgeführt, da beide die gleiche Locking-Technik verwenden (d. h. lock ), so dass der reine Overhead in einer "geraden Linie" vernünftig erscheint.

Meine Benchmark hat die folgenden Ergebnisse für eine Version erstellt:

%Vor%

Verwenden Sie den folgenden Code:

%Vor%     
Tim Lloyd 27.01.2011, 15:24
quelle
6

Wir können das nicht für Sie beantworten. Nur Sie können es selbst beantworten, indem Sie einen Profiler erhalten und beide Szenarien ( Queue.Synchronized vs. Lock ) auf realen Daten Ihrer Anwendung testen. Es kann nicht einmal ein Flaschenhals in Ihrer Anwendung sein.

Das heißt, Sie sollten wahrscheinlich nur ConcurrentQueue verwenden.

    
jason 27.01.2011 15:23
quelle
0
  1. Queue.Synchronize Wraps einer neuen Queue Synchronisiert, während Lock Queue.SyncRoot einem Objekt den Zugriff auf den synchronisierten Queue-Weg gewährt. Auf diese Weise können Sie Thread Safety in der Queue sicherstellen, während Sie die Operationen Enqueue und Dequeue gleichzeitig mit Threads verwenden.
Vishal Patwardhan 18.11.2014 14:07
quelle