2017-12-05 7 views
0

ich Benchmark versuche die folgenden Code,Multi-Thread langsamer als einzigen Thread in Ruby

das Verfahren Rate.rate_by_service, hat einige DB-Aufrufe/Verarbeitung und gibt einen Wert

mutex = Mutex.new 
thread_arr = [] 
puts Benchmark.measure{ 
1000.times do |i| 
    services.each_with_index do |service_obj,index| 
    thread_arr[index] = Thread.new { 
     mutex.synchronize { 
     rate << Rate.rate_by_service(service_obj,@package,@from,@to,@credentials) #does database calls/calcualtions and returns a value 
     } 
    } 
    #rate << 
    end 
    thread_arr.each {|t| t.join} 
end 
} 

Das Merkwürdige i beobachtet haben, ist, dass die Multi-Threaded-Version ist langsamer als die normale Version (ohne Gewinde)

Hier werden die Benchmarking-Ergebnisse sind.

#threading 
4.870000 0.490000 5.360000 ( 6.846712) 
5.300000 0.520000 5.820000 ( 7.550946) 
4.640000 0.480000 5.120000 ( 6.720078) 
4.580000 0.460000 5.040000 ( 6.344415) 
4.510000 0.450000 4.960000 ( 6.312238) 




#no threading 
3.610000 0.240000 3.850000 ( 4.088772) 
3.360000 0.200000 3.560000 ( 3.721254) 
3.380000 0.190000 3.570000 ( 3.795252) 
3.500000 0.200000 3.700000 ( 4.156553) 
3.580000 0.210000 3.790000 ( 4.183601) 

ist da etwas falsch das ich mache? Kann jemand bitte erläutern, warum dieses Verhalten passieren könnte.

ich verwende rubin 2.0 Schienen Schienen 4.2.7.1

+1

Der Mutex emsures, dass Ihre Logik 'Rate.rate_by_service' sequentielly ausgeführt wird, aber fügt Kopf Threading. Ohne den Mutex sollte es schneller gehen. ;-) – sschmeck

+0

aber wird es dann nicht dazu führen, dass einige Werte inkonsistent sind? d. h. Entfernen von Mutex –

+0

Hängt von Ihrer Implementierung von 'Rate.rate_by_service' ab. – sschmeck

Antwort

3

Das gesamte ablauffähigen Block jedes Thread synchronisiert ist, wird der Code macht vollständig synchron, sondern ein Overhead auf Thread-Erzeugung und Kontextschalter eingeführt wird. Was hast du erwartet?

Um es asynchron zu machen, sollte man nur das Original-Array-Update synchronisieren:

1000.times do |_| 
    services.map do |service_obj| 
    Thread.new do 
     result = Rate.rate_by_service(...) 
     mutex.synchronize { rate << result } 
    end 
    end.each(&:join) 
end 

Beachten Sie, dass die Datenbankabfrage, Rate.rate_by_service, außerhalb des Mutex synchronize gemacht.

+0

Dank @mudasobwa, aber wenn ich wie oben tun, mutex.synchronize {Rate << Ergebnis} i get „zirkuläre Abhängigkeit erkannt, während eine konstante ServiceOption selbstladende“ –

+0

Diese völlig unabhängig von der ursprünglichen Frage ist die, warum für diesen Code mehrere war ' Threads sind nicht so leistungsfähig wie ein einzelner. – mudasobwa

+0

ich den Code aktualisiert, wie Sie sufggsted aber immer noch nicht-Threading-Modus ist schneller. Könnte es wegen Active Record Cache sein? Ich sehe viele Ergebnisse, die im Nicht-Threading-Modus aus dem Cache abgerufen werden. –

Verwandte Themen