2010-04-20 8 views
8

Ich entwickle eine Rails 2.3, Ruby 1.9.1 Webapplikation, die vor jeder Anfrage eine Menge Berechnungen durchführt. Für jede Anfrage muss ein Graph mit 300 Knoten und ~ 1000 Kanten berechnet werden. Das Diagramm und alle seine Knoten, Kanten und anderen Objekte werden für jede Anfrage initialisiert (~ 2000 Objekte) - tatsächlich werden sie aus einem nicht berechneten Cache-Graphen mit Marshal.load (Marshal.dump()) geklont.Ruby 1.9 GarbageCollector, GC.disable/enable

Leistung ist ein ziemliches Problem hier. Im Moment dauert die gesamte Anfrage durchschnittlich 150ms. Ich sah dann, dass während einer Anfrage Teile der Berechnung nach dem Zufallsprinzip länger dauern. Unter der Annahme, dass dies der GarbageCollector sein könnte, habe ich die Anfrage in GC.disable und GC.enable verpackt, so dass die Anfrage mit dem Müllsammeln wartet, bis die Berechnung und das Rendering beendet sind.

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

Die durchschnittliche Anforderung dauert jetzt etwa 100 ms (50 ms weniger).

Aber ich bin mir nicht sicher, ob dies eine gute/stabile Lösung ist, ich nehme an, dass es Nachteile haben muss. Hat jemand Erfahrung mit einem ähnlichen Problem oder sieht er Probleme mit dem obigen Code?

Antwort

1

Keine echten Nachteile, außer dass die erneute Aktivierung des GC länger dauern wird.

Es gibt eine Reihe von Artikeln im Internet über den Ruby's GC. Sieh sie dir an und vielleicht kannst du diese Zeilen entfernen. =)

Es gibt keine Möglichkeit, die Ergebnisse im Cache zu speichern und die Berechnungen im Hintergrund alle paar Minuten wiederholen zu können.

+0

Cache nicht möglich, die Berechnung hängt von Benutzereingaben ab. – seb

0

Es sieht vielleicht dumm aus, aber in diesem Fall werde ich versuchen, eine C-Funktion von Ihrem ROR aufzurufen. Diese Lösung ziemlich hardcore ist, aber es sollte erstaunliche Leistung Ergebnisse geben, mit Ruby ist keine lange therm Lösung ist es nur ein fix ...

5

Wenn es Ihre Anwendung schneller macht, dann ist es)

Ihre Lösung zu verwenden .

Ich würde eine ensure Anweisung hinzufügen, so dass, wenn eine Ausnahme ausgelöst wird, Sie nicht mit deaktivierten Garbage Collection enden.

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

das ist sehr hilfreich. Tnx – seb

Verwandte Themen