(同事的原創)關於效率最佳化的一點工作心得

來源:互聯網
上載者:User

此文是單位同事胡計平的一個關於效率最佳化的總結,內容很實用,轉貼到blog裡,以備自己日後查看,也希望能對更多的人有所協助                                

最近寫一程式,跟效率最佳化打上了交道,把其中的體會寫下來,供大家討論分享,我想效率最佳化工作可以分為如下幾個步驟:

(1)尋找影響效率的瓶頸之處:定位的方法當然是使用時間函數,一般精確的使用GetTickCount就可以,非常精確的使用

function GetCycleCount: Int64;
asm
  RDTSC;    //得到當前CPU的刻度數。
end;

想必這個知識大家都應該已經知道了。定位的過程大概是先定位函數,再到一條語句,大多數情況下,效率的問題就是一條語句引起的。不過有幾點值得大家注意,比如在一個函數內使用時間函數測試出來的總時間為1s,然而在該函數調用處使用時間函數測試出來的總時間卻為5s,這個時候如果你稍微疏忽,你很可能定位不到到底是哪裡的問題。這裡就涉及到了一些隱藏的地方,它們消耗了時間,你卻不知道,詳述將在下文。

(2)找到了瓶頸之處,接下來就是分析原因,這個過程可能會遇到很容易的,一看就知道了原因所在,但是更多情況下它會隱藏著,不易發現,需要我們的耐心,細心和信心。分析和尋找問題的原因,我自己總結了下面這些方法或者說可以考慮的方面:

1.是否可以換個核心思想:對於類似解析器,編譯器的程式,很有可能在現有的核心思想下現有的實現方式已經是最優了,幾乎沒有提高的餘地,那麼我們可以想想換個思想。比如XML解析器,微軟提供了Dom,但是它的核心思想已經決定了它就只能那麼快了,並且消耗記憶體巨大,大概是源檔案的5-10倍,SAX的事件驅動模型也決定了它比Dom更快更少耗記憶體,但是新一代的XML解析器VTD-XML(完全基於位元組流解析,沒有對象)也註定了它比所有其他的XML解析器具有更多的優勢!

2.演算法代碼編寫是否正確:前陣子,姚柯跟我說,公用資源的排序類中有一個條件寫反了,使得該使用二分尋找的地方使用了普通尋找,修改後發現構造交叉表的效率提高10倍以上,整體查詢效率提高7-8倍,從這個事件中我們可以看到考慮演算法代碼正確與否是很有必要的,有時候問題就隱藏在其中,而且隱藏得很深!

3.演算法選擇是否恰當:很明顯,如果你使用了冒泡排序,怎麼也快不了。當然大部分情況不會是這樣的,更多情況是要考慮當前情況和環境來選擇的,很有可能平時我們認為效率基本一樣的多種演算法,但是在當前情況下可能就只有一種最恰當,但不幸地是之前我們選擇錯了,那麼現在你就有了改進的機會!

4.是否不必要的迴圈次數過多:有時候多出很多不必要的迴圈,但是不易發現,我們在最佳化的時候,這是個重點考慮的對象,除非你已經極其肯定就是要運行這麼多次,否則要一次又一次的懷疑自己的觀點。

5.關鍵函數中是否有很多的string參數:我說的關鍵函數是指調用次數很多。關鍵函數中最好不要申明string,動態數組之類的臨時變數,因為它們在該函數最開始有隱藏的初始化,在函數結尾有隱藏的釋放。我曾經在一個關鍵函數中申明了一個動態數組,測試效率的時候,在定位的時候就出現了(1)中提到的現象,原來是臨時變數導致的,最後改造函數,去掉臨時變數,函數效率馬上提高一倍!

6.是否因為派生機制導致效率問題:我在寫一個程式的時候,其中涉及到了派生關係,由於派生體系中的一個方法A被使用者調用的次數非常多,達百萬次以上。開始的時候也是最佳化函數內部,但是後來發現函數內部不可能再最佳化了,但是整體效率還是差一些,於是苦思冥想,發現我用了派生機制,每次調用該方法的時候,都要去VMT表尋找,消耗了一些時間,不要小看這個,當調用次數巨大的時候,你會發現這個原因影響很大。當我去掉了派生關係,直接用靜態方法的時候,整體效率提高一倍多,不得不說讓人欣喜!

7.是否介面使用不恰當:介面使用不恰當可能的原因有:你對此不熟悉;介面本身提供的就有迷惑性。比如你對公司的平台不熟悉,那麼很可能出現使用不當,導致效率出現問題,這就是典型的不熟悉的原因;我最近做一個跟word有關係的程式,其中一個要求就是得到word的文件引導模式。在遍曆word編程介面中的Paragraphs介面時,開始看了介面原型,發現有Count,Item(AIndex)等屬性和方法,於是就用了for迴圈遍曆,但是測試效率時發現當Count有2000多個的時候,居然需要180s才能遍曆完成!我怎麼也不相信這麼慢,於是開始定位,發現居然是iParagraph := iParagraphs.Item(I)這行代碼巨慢,它用了160s。但是我不太相信微軟提供的遍曆介面會有這麼慢,於是去介面原型中尋找其他途徑,果然我有了新發現,在Paragraph介面中有Next,Previous方法,所以可以進行迭代式遍曆,換成迭代式訪問後,馬上只需要20s了,所以估計它內部是鏈式儲存。事後想,象微軟提供的這樣的介面,真的很有迷惑性,兩種遍曆方式,但是相差甚遠!值得我們思考和注意!

(3)找到了原因之後,我想較多情況下還是可以找到解決問題的辦法,當然也有很多不好解決的,就象上面(2)提到的第一點原因。還是那句話,更多的是需要我們更耐心,細心和信心,當然開闊的思維和思考是最基礎,最重要的!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.