2010-04-20 102 views
8

我正在開發一個Rails 2.3,Ruby 1.9.1 web應用程序,它在每次請求之前執行相當多的計算。對於每個請求,它必須計算一個具有300個節點和〜1000個邊的圖。該圖及其所有節點,邊緣和其他對象都針對每個請求進行初始化(〜2000個對象) - 實際上,它們是使用Marshal.load(Marshal.dump())從未計算的緩存圖形中克隆的。Ruby 1.9 GarbageCollector,GC.disable/enable

性能在這裏是一個相當大的問題。現在整個請求平均需要150ms。然後我看到,在請求期間,部分計算隨機需要更長的時間。假設這可能是垃圾收集器踢入,我將請求包裝在GC.disable和GC.enable中,以便請求等待垃圾收集,直到計算和渲染完成。

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

平均請求現在需要大約100ms(少50ms)。

但我不確定這是否是一個好的/穩定的解決方案,我認爲這樣做肯定有缺點。有沒有人有類似問題的經驗,或看到上述代碼的問題?

回答

1

沒有真正的缺點,除了重新啓用GC時需要更長的時間才能運行。

網上有很多關於調整Ruby的GC的文章。看看他們,也許你可以刪除這些線。 =)

您無法緩存結果並每隔幾分鐘就在背景上重新計算一次?

+0

不可能緩存,計算取決於用戶輸入。 – seb 2010-04-20 12:28:13

0

它可能看起來很愚蠢,但在這種情況下,我會嘗試從ROR調用C函數。 該解決方案是相當硬派,但它應該給驚豔表現的結果;)

您與紅寶石的解決方案是不是一個長期的解決方案千卡它只是一個修復...

5

如果它使你的應用程序更快,然後使用它。

我會添加一個ensure語句,以便如果發生任何異常,最終不會收到禁用的垃圾回收。

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

這非常有幫助。 TNX – seb 2010-04-20 21:49:50