2011-11-05 13 views
9

Mam więc tablicę 40000 elementów i chcę uruchomić metodę dla każdego elementu.Ruby - jak uruchomić metodę dla każdego elementu tablicy na różnych wątkach?

Aby skrócić czas potrzebny, myślę o uruchomieniu tego na wielu wątkach. Być może podział macierzy na wiele tablic i działanie na innym wątku lub czymś podobnym. Ale nie wiem, jak zacząć.

Powiedz, że tablica jest foo [], a metoda wywołania to bar(). bar() zwraca ciąg znaków. Po wykonaniu kodu chcę móc łączyć wszystkie ciągi razem w jeden duży ciąg.

Czy istnieje sposób, aby to zrobić? Starałem się, aby moje pytanie było jak najprostsze, ale jeśli chcesz uzyskać więcej informacji, daj mi znać.

Z góry dziękuję!

Odpowiedz

1

Gdybym właściwie zrozumieć, trzeba coś w tym fragmencie:

foo = %w{1 2 3} # => ["1", "2", "3"] 

# in your case it would be some time-consumed operation on string 
def inc(element) 
    element.succ 
end # => nil 
inc("1") # => "2" 

threads = foo.map do |f| 
    Thread.new { inc(f) } 
end 
# => [#<Thread:0x8d28694 run>, #<Thread:0x8d28630 run>, #<Thread:0x8d28590 run>] 

threads.map { |t| t.value } # => ["2", "3", "4"] 
3

Brzmi to jak chcesz coś w rodzaju funkcji pmap. Istnieje biblioteka ruby ​​o nazwie peach, która zapewnia zarówno metodę pmap, jak i brzoskwiniową ("równoległą") w macierzystych tablicach.

Dzięki tej bibliotece, można zrobić coś jak

require 'peach' 
[1,2,3,4].pmap{|x| f(x)} #Spawns 4 threads, => [f(1),f(2),f(3),f(4)] 
+2

chyba warto wspomnieć, że 'a.pmap (n) {...}' mogą być wykorzystywane do ograniczania się tylko do 'n' wątków, komputer Gbert90 byłby prawdopodobnie denerwować się z nim jeśli próbował uruchomić wątki 40k. –

+0

Próbowałem tego, ale nie działało dla dużej tablicy. Czy istnieje jakiś artykuł/książka, która może w tym pomóc? – Gbert90

+0

Jak duża jest twoja tablica? Czy próbowałeś ograniczyć liczbę wątków, jak sugerowano w powyższym komentarzu, za pomocą 'a.pmap (n) {...}'? Tylko upewnij się, że n <= # procesora w twoim systemie. – drsnyder

3

Istnieje wiele sposobów, aby osiągnąć współbieżności, a przy użyciu wątków jest jeden sposób. Jednak najlepsza wydajność zależy od wybranego środowiska wykonawczego Ruby.

Na przykład, jednym prostym sposobem na wielowątkowe jest biblioteka "brzoskwinia" (równoległa) http://peach.rubyforge.org/. Jednak działa to najlepiej na JRuby, który używa natywnych wątków.

Dla środowiska wykonawczego MRI można użyć wielu procesów, takich jak DRb lub magistrali komunikatów, takich jak RabbitMQ.

dla wielkiej writeup z wielu opcji, zobacz ten wpis: http://merbist.com/2011/02/22/concurrency-in-ruby-explained/

0

Inną opcją jest użycie Eventmachine, który pozwala na uruchamianie „” pseudo-równolegle na jednym wątku. Zobacz EM::Iterator - na przykład:

ret = nil 

EM.run do 

    # run 10 at a time; you can set the concurrency level to whatever you want 
    # but processing will slow down depending on how costly your bar method is 

    EM::Iterator.new(foo, 10).map( 
    proc{|item, iter| iter.return(item.bar)}, 
    proc{|results| ret = results.join; EM.stop} 
) 

end 
Powiązane problemy