2010-02-17 10 views
5

Estaba buscando un ejemplo en línea que demostrara un temporizador en ruby ​​y me encontré con el siguiente código. Funciona como se esperaba pero ¿tiene sentido que este simple programa use 30Mo de memoria (como se muestra en el administrador de tareas de Windows) y demasiada CPU?Temporizador en rendimiento de Ruby

Muchas gracias

def time_block 
    start_time = Time.now 
    Thread.new { yield } 
    Time.now - start_time 
end 

def repeat_every(seconds) 
    while true do 
    time_spent = time_block { yield } # To handle -ve sleep interaval 
    sleep(seconds - time_spent) if time_spent < seconds 
    end 
end 

repeat_every(5) { 
} 
+1

No me puedo imaginar cómo ese código tiene sentido ... Los hilos no están unidas, por lo que siempre habrá time_spent 0 y el bucle simplemente acumula hasta subprocesos que se ejecutan en paralelo si la carga de trabajo del ther tarda más de 5 segundos. – hurikhan77

+0

Gracias hurikhan77, ¿te importa señalarme un doc o un libro sobre hilos para no tener que hacer preguntas estúpidas;)? – Elsanto

+0

http://ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html –

Respuesta

11

Como se señaló en los comentarios a la pregunta, todo lo que necesita para hacer que funcione es que se inscribe en el hilo:

#!/usr/bin/ruby1.8 

def repeat_every(interval, &block) 
    loop do 
    start_time = Time.now 
    Thread.new(&block).join 
    elapsed = Time.now - start_time 
    sleep([interval - elapsed, 0].max) 
    end 
end 

repeat_every(5) do 
    puts Time.now.to_i 
end 

# => 1266437822 
# => 1266437827 
# => 1266437832 
... 

Sin embargo, ya que se encuentra , no hay razón para usar hilos para el código en la pregunta: ¿

def repeat_every(interval) 
    loop do 
    start_time = Time.now 
    yield 
    elapsed = Time.now - start_time 
    sleep([interval - elapsed, 0].max) 
    end 
end 

repeat_every(5) do 
    puts Time.now.to_i 
end 

# => 1266437911 
# => 1266437916 
# => 1266437921 

Ahora bien, si lo que quiere es un hilo º at hace algo a intervalos, para que el programa principal pueda hacer otra cosa, luego envolverá todo ese ciclo en un hilo.

def repeat_every(interval) 
    Thread.new do 
    loop do 
     start_time = Time.now 
     yield 
     elapsed = Time.now - start_time 
     sleep([interval - elapsed, 0].max) 
    end 
    end 
end 

thread = repeat_every(5) do 
    puts Time.now.to_i 
end 
puts "Doing other stuff..." 
thread.join 

# => 1266438037 
# => Doing other stuff... 
# => 1266438042 
# => 1266438047 
+0

Muchas gracias Wayne. Última pregunta: el código aún ocupa 30Mo en la memoria virtual en Windows, ¿es eso normal? ¡Muchas gracias! – Elsanto

+0

@Elsanto, no sé qué es lo normal en Windows. En Linux, "dormir 10; salir" ocupa alrededor de 9 MB; el código anterior, alrededor de 16 MB. –

+0

Se necesita mucha memoria porque Ruby es un lenguaje dinámico que se ejecuta en una máquina virtual Ruby. Si traduces eso a C, apuesto a que no obtendrás más de 1 Mb de memoria usag (a menos que tengas pérdidas de memoria). Pero en un mundo en el que 8,000,000 Mb cuestan alrededor de 50 dólares, creo que 30 Mb ($ 0,0001875 dll) no es un problema. –