再探Ruby效能

From The Joel on Software Translation Project

Jump to: navigation, search

這篇文字於2006年9月12日張貼在約耳談軟體首頁。

Jack Herrington針對Ruby on Rails的效能議題寫電郵給我,信上寫著:

我同意你關於Unicode的說法,也同意Rails需要時間發展。不過我用了一堆的Web技術,每個都有問題。 我倒是不同意你對可擴充性(scalability)的說法。我不認為Rails有那種其他技術所沒有,而且無法克服的擴充性問題。 我希望你至少能把你對擴充性的說法講得更清楚。告訴我們是什麼樣的擴充性問題。即使我們無法替你解決,整個社群還是能由你的經驗有所收獲。

David Heinemeier Hansson寫著:

Rails對絕大多數的web應用而言已經夠快了。我們有每天處理數百萬個動態網頁的網站。如果你的目標是做出像Yahoo或Amazon的首頁,大概沒有基於任何語言的現成框架能做得好。你很可能得自己來。不過當然啦,我也是喜歡讓CPU閒一點。不過恰巧的是,我更希望能讓開發者更閒,所以願意犧牲前者來獲得後者。

順便澄清一下,我在意的是Ruby而不是Rails的效能。原因如下:

我看過許多拿Java(對我而言不算快)之類的bytecode語言和Ruby效能對照的比較,而且我也看到很多效能報告聲稱Ruby慢十倍慢五十倍云云。除了少數的網誌鬼扯外,Ruby在電腦語言對抗評比上幾乎是穩吊車尾了。

我並不知道Ruby實作的細節,不過我猜最大的問題大概是在晚期連結(late binding)以及最主要的鴨子型別處理(duck typing)吧,有了後者就不能用型別參考或是強型別處理。這表示函數的呼叫一定會慢,因為你永遠沒有辦法把函數呼叫編譯成單一個x86指令集的 CALL指令...你一定得探索物件,甚至可能要掃瞄一個雜湊表才能找到所要呼叫的函數。呼叫物件的方法是個極為常用的操作,在純物件導向的語言中更是如此。有些語言的物件型別可以在編譯時期決定,所以跳躍的指令可以在編譯時得到(如C語言),或是透過單一個vtable用一個間接指令取得(如C++中)。Ruby至少得把那一小段程式碼,化簡成一個間接CALL的CPU指令,才能提供和這類語言相當的效能。

我瞭解開發時間比CPU時間更重要的原理,不過坦白說那只不過是保險桿貼紙上的口號,對抱怨效能的人來說並不公平。敝公司的產品FogBugz似乎應該很適合用Ruby on Rails開發,不過其中還是有些地方的效能極為重要。FogBugz 6裡就有個地方,得進行數百萬次運算才能在單一個網頁上顯示一個圖表。我們在目前的開發環境下做了許多最佳化,才把運算時間縮到三秒左右。坦白地說,如果是用duck-typed函數呼叫的話,我不認為我們能在網頁瀏覽器逾時前或在合理時間內完成。我們也必須用Bayesian過濾器掃瞄進入的電郵訊息。這個計算密集的操作過濾一個訊息約要一秒。對我們很多客戶而言,每秒收到一封電子郵件並不算離譜,所以現在的效能非常接近CPU運算能力的極限。而這已經是用一種執行這類程式碼比Ruby快數個量級的語言了。改用Ruby的話我們穩死無疑。

就算是典型單純的CRUD應用程式,也就是那種只是由資料庫讀個資料表顯示出來,讓你增刪編輯各筆資料的應用程式,在深入到程式碼某處時,都常會發現某些需要密集運算的動作。比如網誌軟體可能會要用Bayesian過濾器來消除垃圾意見。你在這種地方就會突然明白,你所選的語言比競爭者慢上十倍,於是你根本就無法加上該功能,不然就得呼叫另一種語言(並且承受附帶的轉換整編(marshalling)負擔)。

並不是每個人都會遇到這種問題,不過當人們說遇到Ruby的效能問題,或僅僅只是想讓程式執行得比核心的Ruby語言引擎更快時,Ruby擁護者唱歌頌讚「開發者時間與CPU時間」是沒有用的。就算你不做需要密集運算的東西,如果發現自己得買100台伺服器而非10台時,你可能就會突然重新思考整個開發者時間與CPU時間的方程式。

我瞭解有些計畫要用某種bytecode編譯器來處理Ruby的效能問題,這很不錯。當這些計畫實現而且Ruby也出現具競爭力的效能評比後,對各式各樣的應用可能會更為適合。不過在那之前,我還是會聲稱並非每種狀況都適合使用Ruby。

關於作者: 我是本站站長Joel Spolsky,是一位紐約市的軟體開發者。我從2000年起在本站撰寫與軟體開發、管理、商業以及Internet相關的文章。我平日的工作是經營Fog Creek Software這家公司,產品包括FogBugz這個有個蠢名字但聰明的問題追蹤軟體,還有透過Internet最簡易的遠端技術支援方案Fog Creek Copilot,完全不用安裝或設定。

Personal tools