評《最容易被人忽略的基本代碼最佳化技術》

來源:互聯網
上載者:User

http://sunxiunan.com/?p=1749

這篇文字主要來自我在TopLanguage討論群組裡面的發言,僅作總結留記。

首先要介紹一下原文作者Walter Bright,從他首頁可見他是一個很牛的程式員,主要工作領域是寫編譯器。這個背景很重要,這是原文第二條的主要基礎。但是也要注意到,一百個程式員裡面也許都沒有一個知道如何編寫編譯器,知道如何讀寫彙編的程式員比例也許會高一些,但不會很高,估計也就是百分之幾的樣子,比如我只會讀一些簡單的彙編代碼,但是不會寫。

這篇文章認為Profiling和看組合語言如何被啟動並執行是兩個基本技術,我在討論中也沒有提到寫彙編,因為會讀的人要比會寫的多出不少。但是看彙編真的不是一種基本的最佳化代碼手段。

首先這個代碼就很值得討論,Javascript算不算代碼?Ruby on rails或者Django這些架構算不算?或者Mono、Java、DotNet算不算代碼?這些領域的程式員,很少有人會從組合語言層面來做代碼最佳化。如果你是一個類似項目的Team leader,組員說他最近在讀某Rails項目的彙編代碼,想找出慢的原因並加以改進,建議你立刻把他開掉,因為要麼他是在磨洋工,要麼是腦袋壞掉了。

Profiling是最佳化代碼的必要手段,而不是什麼可以被忽略的技術。實在無法想象沒有做Profiling,如何找出系統瓶頸,如何做代碼最佳化。換句話說,沒有Profiling其實也就沒有基準資料,怎麼保證你修改的代碼一定是最佳化的?!從這一點上說,忽略Profiling來進行最佳化,很難想象。

關於Windows下的Profiling,我以前寫過一篇部落格Profiling C++ performance in Windows http://sunxiunan.com/?p=1216 (名字雖然是英文的,但的確是我寫的),裡面介紹了一些我看到的或者用過的Profiling技術,頗為簡陋,但也幫我做了不少代碼最佳化相關的工作。

正常一個通用的代碼最佳化過程應該是這樣的:

1)使用者提出效能有問題。如果沒有人提出,那就盡量不要作修改,因為最佳化往往會帶來更為混亂的代碼,或者一些很難理解維護的代碼關係。

2)詢問使用者他們期望達到的運行速度是什麼。因為最佳化往往是在這裡做做在那裡改改,如果達到了期望值就要立刻停下來,否則過猶不及。

3)對當前系統做Profiling,收集運行資料。要注意Profiling會多少導致系統運行速度變慢,如何擷取正確的運行資料,需要做一些編程工作。並不是拿來一個工具就一定會找到問題。另外還要確認Profiling資料本身是正確的,否則最佳化多半會是徒勞的。

4)取得資料以後對系統做逐步改進。這一步要注意的是每一步改進都要儘可能的獨立、可回退,每做一步改進都要做一次新的Profiling,保證修改以後的代碼真正有了速度上的提升。如果對效能提升效果不明顯,就不要引入這個修改,哪怕你在上面投入了很多精力,要敢於捨棄。另外做代碼最佳化要著眼全域,不能局部最佳化了,但是整體運行速度下降。另外要注意對於每一次修改,應該有相應的測試手段保證修改不會影響系統運行。基本上這些最佳化代碼都會引入一些新的bug。關於效能最佳化,有一篇很不錯的文章可以參考http://csbabel.wordpress.com/2010/04/29/interviewbible-1-speed-optimization/

5)代碼最佳化達到期望值以後,停止最佳化過程,記錄相關資料以及最佳化方法,留作以後查詢。

我們這裡只提代碼最佳化,其實最佳化還有很多其它手段,比如添加更好的硬體,換一個快的資料庫或者做做資料庫調優,改改系統參數,換一個更快的webserver,最佳化本來就是一個系統工程,光看某一個點很難做好最佳化,應該有全域觀點。

至於看彙編代碼找問題,主要是針對C程式員或者C++程式員。但是要知道現在的編譯器技術發展與8086時代是完全不一樣了,編譯配置是完全最佳化的代碼,你很難從運行中看出問題,產生的彙編代碼也很難讀懂。這也是我很不推薦大家用看彙編來做最佳化的原因,有時間可以找到更多更嚴重的系統瓶頸。如果要從彙編層看問題,首先要看懂彙編代碼,然後還要會改彙編代碼,投入產出比例差太大。而且找到問題就看彙編,容易陷入細節,要時刻牢記最佳化應從大處著眼,抓大放小才是硬道理,我算是一個比較普通的VisualC++程式員,也做過一些簡單的效能最佳化,基本上用不到看彙編就知道問題所在,profiling是最有用的也是唯一的工具。當然對於作者這樣寫編譯器的程式員而言,看彙編寫彙編是他們的日常工作,那就另當別論,但不能推而廣之。

另外需要強調的是,雖然不建議大家在最佳化時看彙編,但對於程式員來說,學習時深入到彙編這一層是非常有協助的。比如一些常見的問題如calling conversions(http://sunxiunan.com/?p=1229),i++和++i有什麼區別,const一些研究http://sunxiunan.com/?p=870 都是看到彙編代碼以後就比較容易理解。

總而言之,任何一個程式員要知道如何做代碼最佳化,應該瞭解代碼最佳化的基本步驟,自己相關領域的一些常見效能問題的模式,自己工作領域常見的Profiling方法和最佳化工具。有的放矢才能更好的工作。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.