2011-11-05 10 views
9

Así que tengo una matriz de 40000 elementos, y deseo ejecutar un método en cada elemento.Ruby: ¿cómo ejecuto un método en cada elemento de la matriz en diferentes subprocesos?

Para reducir el tiempo que tomará, estoy pensando en ejecutar esto en varios hilos. Tal vez dividir la matriz en múltiples matrices y ejecutar en un hilo diferente o algo así. Pero no sé cómo comenzar.

Digamos que la matriz es foo [], y el método para llamar es bar(). bar() devuelve una cadena. Después de que se ejecuta el código, quiero poder combinar/sumar todas las cadenas en una cadena grande.

¿Hay alguna manera de hacerlo? Traté de mantener mi pregunta lo más simple posible, pero si quieres más información, házmelo saber.

¡Gracias de antemano!

Respuesta

1

Si entiendo correctamente, es necesario algo así como este fragmento:

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

Parece que usted quiere algo así como una función pmap. Hay una biblioteca de ruby ​​llamada peach que proporciona tanto un método pmap como uno de melocotón ("paralelo" cada uno) en las matrices nativas.

Con esta biblioteca, se puede hacer algo como

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

Probablemente vale la pena mencionar que 'a.pmap (n) {...}' puede ser utilizado por qué limitarse a sólo 'N' hilos, equipo de Gbert90 probablemente se molesta con él si intentó lanzar 40k hilos. –

+0

Intenté esto, pero no funcionó para una matriz grande. ¿Hay algún artículo/libro que pueda ayudar con esto? – Gbert90

+0

¿Qué tan grande es tu matriz? ¿Intentó limitar el número de subprocesos como se sugiere en el comentario anterior con 'a.pmap (n) {...}'? Solo asegúrate de que n <= # de CPU en tu sistema. – drsnyder

3

Hay muchas maneras de lograr la concurrencia, y el uso de hilos es una forma. Sin embargo, el mejor rendimiento depende del tiempo de ejecución de Ruby que elija.

Por ejemplo, una forma simple de multiprocesamiento es la biblioteca 'melocotón' (paralelo a cada uno) http://peach.rubyforge.org/. Sin embargo, esto funciona mejor en JRuby, que usa subprocesos nativos.

Para el tiempo de ejecución de MRI es posible que desee utilizar procesos múltiples como DRb o un bus de mensajes como RabbitMQ.

Para una gran valoración crítica de las muchas opciones, vea este post: http://merbist.com/2011/02/22/concurrency-in-ruby-explained/

0

Otra opción es utilizar EventMachine, lo que le permite ejecutar 'pseudo-paralelo' en un solo hilo. Ver EM::Iterator - por ejemplo:

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 
Cuestiones relacionadas