代碼調優及其他zz

看了CoolShell最近的一篇文章《性能調優攻略》我這隻把我比較感興趣的代碼調優部分貼出來留作備份,其他部分的調優策略可以點連接看原文。之前做的Api監控系統和自然語言的一個情感分析,都用到了海量數據的輸入輸出,對代碼優化這裏感觸甚多,比如數據結構的選擇,異常的處理方式,還有該文中說到的變量類型選擇,多線程控制,在做這種數據量交換很大的模塊時,這些方面就要好好去斟酌了。

4.2)代碼調優。從我的經驗上來說,代碼上的調優有下面這幾點:

  • 字符串操作。這是最費系統性能的事了,無論是strcpy, strcat還是strlen,最需要注意的是字符串子串匹配。所以,能用整型最好用整型。舉幾個例子,第一個例子是N年前做銀行的時候,我的同事喜歡把日期存成字符串(如:2012-05-29 08:30:02),我勒個去,一個select  where between語句相當耗時。另一個例子是,我以前有個同事把一些狀態碼用字符串來處理,他的理由是,這樣可以在界面上直接顯示,後來性能調優的時候,我把這些狀態碼全改成整型,然後用位操作查狀態,因爲有一個每秒鐘被調用了150K次的函數裏面有三處需要檢查狀態,經過改善以後,整個系統的性能上升了30%左右。還有一個例子是,我以前從事的某個產品編程規範中有一條是要在每個函數中把函數名定義出來,如:const char fname[]=”functionName()”, 這是爲了好打日誌,但是爲什麼不聲明成 static類型的呢?
  • 多線程調優。有人說,thread is evil,這個對於系統性能在某些時候是個問題。因爲多線程瓶頸就在於互斥和同步的鎖上,以及線程上下文切換的成本,怎麼樣的少用鎖或不用鎖是根本(比如:多版本併發控制(MVCC)在分佈式系統中的應用 中說的樂觀鎖可以解決性能問題),此外,還有讀寫鎖也可以解決大多數是讀操作的併發的性能問題。這裏多說一點在C++中,我們可能會使用線程安全的智能指針AutoPtr或是別的一些容器,只要是線程安全的,其不管三七二十一都要上鎖,上鎖是個成本很高的操作,使用AutoPtr會讓我們的系統性能下降得很快,如果你可以保證不會有線程併發問題,那麼你應該不要用AutoPtr。我記得我上次我們同事去掉智能指針的引用計數,讓系統性能提升了50%以上。對於Java對象的引用計數,如果我猜的沒錯的話,到處都是鎖,所以,Java的性能問題一直是個問題。另外,線程不是越多越好,線程間的調度和上下文切換也是很誇張的事,儘可能的在一個線程裏幹,儘可能的不要同步線程。這會讓你有很多的性能。
  • 內存分配。不要小看程序的內存分配。malloc/realloc/calloc這樣的系統調非常耗時,尤其是當內存出現碎片的時候。我以前的公司出過這樣一個問題——在用戶的站點上,我們的程序有一天不響應了,用GDB跟進去一看,系統hang在了malloc操作上,20秒都沒有返回,重啓一些系統就好了。這就是內存碎片的問題。這就是爲什麼很多人抱怨STL有嚴重的內存碎片的問題,因爲太多的小內存的分配釋放了。有很多人會以爲用內存池可以解決這個問題,但是實際上他們只是重新發明了Runtime-C或操作系統的內存管理機制,完全於事無補。當然解決內存碎片的問題還是通過內存池,具體來說是一系列不同尺寸的內存池(這個留給大家自己去思考)。當然,少進行動態內存分配是最好的。說到內存池就需要說一下池化技術。比如線程池,連接池等。池化技術對於一些短作業來說(如http服務) 相當相當的有效。這項技術可以減少鏈接建立,線程創建的開銷,從而提高性能。
  • 異步操作。我們知道Unix下的文件操作是有block和non-block的方式的,像有些系統調用也是block式的,如:Socket下的select,Windows下的WaitforObject之類的,如果我們的程序是同步操作,那麼會非常影響性能,我們可以改成異步的,但是改成異步的方式會讓你的程序變複雜。異步方式一般要通過隊列,要注間隊列的性能問題,另外,異步下的狀態通知通常是個問題,比如消息事件通知方式,有callback方式,等,這些方式同樣可能會影響你的性能。但是通常來說,異步操作會讓性能的吞吐率有很大提升(Throughput),但是會犧牲系統的響應時間(latency)。這需要業務上支持。
  • 語言和代碼庫。我們要熟悉語言以及所使用的函數庫或類庫的性能。比如:STL中的很多容器分配了內存後,那怕你刪除元素,內存也不會回收,其會造成內存泄露的假像,並可能造成內存碎片問題。再如,STL某些容器的size()==0  和 empty()是不一樣的,因爲,size()是O(n)複雜度,empty()是O(1)的複雜度,這個要小心。Java中的JVM調優需要使用的這些參數:-Xms -Xmx -Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold,還需要注意JVM的GC,GC的霸氣大家都知道,尤其是full GC(還整理內存碎片),他就像“恐龍特級克賽號”一樣,他運行的時候,整個世界的時間都停止了。
 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章