2010-04-20 10 views
8

Estoy desarrollando una aplicación web Rails 2.3, Ruby 1.9.1 que hace un montón de cálculos antes de cada solicitud. Para cada solicitud tiene que calcular un gráfico con 300 nodos y ~ 1000 bordes. El gráfico y todos sus nodos, bordes y otros objetos se inicializan para cada solicitud (~ 2000 objetos); en realidad, se clonan desde un gráfico en caché no calculado utilizando Marshal.load (Marshal.dump()).Ruby 1.9 GarbageCollector, GC.disable/enable

El rendimiento es un gran problema aquí. En este momento, toda la solicitud toma en promedio 150ms. Luego vi que durante una solicitud, partes del cálculo toman más tiempo al azar. Asumiendo que esto podría ser el GarbageCollector, envolví la solicitud en GC.disable y GC.enable, de modo que la solicitud espere con garbagecollecting hasta que el cálculo y la renderización hayan finalizado.

def query 
    GC.disable 
    calculate 
    respond_to do |format| format.html {render} end 
    GC.enable 
end 

La solicitud promedio ahora toma alrededor de 100ms (50 ms menos).

Pero no estoy seguro si esta es una solución buena/estable, supongo que debe haber inconvenientes al hacerlo. ¿Alguien tiene experiencia con un problema similar o ve problemas con el código anterior?

Respuesta

1

Sin desventajas reales, excepto que cuando se vuelve a habilitar el GC tardará más tiempo en ejecutarse.

Hay una serie de artículos en la web sobre la sintonización de Ruby's GC. Échales un vistazo, y tal vez puedas eliminar esas líneas. =)

¿No hay manera de que pueda almacenar en caché los resultados y volver a hacer los calcs en el fondo cada pocos minutos?

+0

No es posible almacenar en caché, el cálculo depende de la entrada del usuario. – seb

0

Puede parecer estúpido, pero en este caso, intentaré llamar a una función C desde su ROR. Esta solución es muy duro, pero debe dar resultados sorprendentes de rendimiento;)

Su solución con el rubí no es una solución a largo termia es sólo una solución ...

5

Si hace que su aplicación más rápido, a continuación, utilizarlo .

Agregaría una declaración ensure para que, si se produce alguna excepción, no termine con la recolección de basura deshabilitada.

def query 
    GC.disable 
    calculate 
    respond_to do |format| format.html {render} end 
ensure 
    GC.enable 
end 
+0

eso es muy útil. tnx – seb

Cuestiones relacionadas