sábado, 14 de abril de 2012

Ruby en paralelo

Para la aportación de esta semana, hablaré acerca de un lenguaje de programación, llamado Ruby, algunos de mis compañeros tal vez ya lo conozcan ya que recuerdo que vimos algo de ello en lenguajes de programación hace algunos semestres.

Ruby es un lenguaje de programación que abarca diferentes paradigmas entre ellos podemos decir, que Ruby es un lenguaje interpretado, reflexivo y también orientado a objetos, inspirado en Python y Perl, para esta entrada hablaré de como poder utilizar este lenguaje en forma paralela.

Ruby por default viene instalado en sistemas operativos de Mac OS a diferencia de Ubuntu, en donde para instarlo debemos de seguir el tipico comando.


Luego de instalarlo, existe un gestor de paquetes para el lenguaje de programación Ruby, llamado RubyGems, en donde podemos portar librerías para Ruby, por lo que necesitamos instalarlo para poder tener la extensión paralela, por lo que pondremos en el terminal.


Ahora con todo esto, lo que necesitamos es la estensión paralela de ruby, para eso simplemente vamos a utilizar el siguiente comando (Ahora lo pondré en Mac OS, pero es lo mismo que en Ubuntu).


Ahora que tenemos todo instalado, vamos a probar si esto funciona correctamente, la extensión parallel para ruby es poderosa, ya que podemos correr cualquier código en procesos paralelos, para utilizar los recursos del CPU o tambien utilizar hilos, así generando código más eficiente.

Para este caso, modifiqué un código realizado aquí en donde se realiza un benchmark entre como de una forma secuencial, mandamos ping host a diferentes páginas web, luego por medio de hilos, luego por medio de bifuración, como lo hemos visto en la materia, teniendo los siguientes resultados.


Obteniendo resultados favorables al utilizar Hilos y Forks, por lo que podemos ver considerablemente el cambio en tiempo.

PD: ara poder hacer funcionar el código pongan cambien las páginas hosts, pongan otras, las que ustedes quieran, porque las que vienen en el ejemplo, hay 2 que ya no existen.

Expongo el código.

require 'rubygems'
require 'parallel'
require 'net/http'
require 'benchmark'


hacer_ping = lambda { |host| 10.times { Net::HTTP.new(host).head('/') } }
puts "#{Parallel.processor_count} procesador(es)"
hosts = ['www.facebook.com', 'www.google.com', 'www.yahoo.com', 'www.uanl.mx', 'www.wikipedia.org', 'www.ruby-lang.org']

Benchmark.bm do |x|
  x.report('Normal') { 
    hosts.each &hacer_ping
  }
  x.report('Hilos') { 
    Parallel.each(hosts, :in_threads => Parallel.processor_count, &hacer_ping)
  }
  x.report('Forks') { 
    Parallel.each(hosts, &hacer_ping)
  }
end 

Ahora modifiqué el código para que hiciera una simple división 100 millones de veces
Expongo el código.

require 'rubygems'
require 'parallel'
require 'benchmark'

div = lambda { 100000000.times { 4.0/2.0 } }
puts "#{Parallel.processor_count} procesador(es)"
 
Benchmark.bm do |x|
  x.report('Normal') { 
    hosts.each &div
  }
  x.report('Hilos') { 
    Parallel.each(hosts, :in_threads => Parallel.processor_count, &div)
  }
  x.report('Forks') { 
    Parallel.each(hosts, &div)
  }
end


Y aquí los resultados.


1 comentario:

  1. Muy bien; 8 para el lab. Corro tu punto extra para la semana que viene.

    ResponderEliminar