程式的核心--複雜度

來源:互聯網
上載者:User

標籤:編程   複雜度   


在《the art of unix programming》中,複雜度的控制被看的非常的重,裡面一句話提到編程項目的核心就是對於複雜度的控制,以及simple原則其實也在講這個事情。
我自己在08年也寫了關於這個的話題:http://blog.csdn.net/toughbro/article/details/2679254
7年過去了,也經曆了《天涯明月刀》這樣的重型項目的磨練,也有了更多的認識。

複雜度控制的實際意義
先從實用的角度來看:關乎運行效率和開發效率(當然其他的擴充性等等也會包括,但是實際在項目裡的感受是這兩個尤其的明顯)。
其實7年前我也是毫無疑問的這麼認為的,但是實踐起來並不是一碼事情,大約幾年前,才真正的形成開發的原則。
開發效率

這個最深刻的認識原則當初開發地形系統,包括從編輯器的底層部分(UI部分是另外一個同事做的)以及runtime部分,從材質到高度圖,系統龐大而且複雜。
開發過程中,也不可避免的遭遇到需求變動(包括材質系統的能力,地圖大小這種非常顛覆性的)。
時間緊任務重,一直想盡量快點把東西做好,開發過程中,代碼整理和系統整體控制沒有做太多,然後其他組可以同步進行,然後再進行代碼整理。
但是對於一個龐大的系統,這種策略就不好。
寫程式的時候,品質和效率最好的情況就是始終對於整個系統,在代碼層級保持一個非常清晰的狀態,你心裡知道要寫成什麼樣,寫的過程,整體的代碼也清晰合理,與你心裡的樣子相印證,然後可以心如止水的一直非常快的寫,整個過程非常的享受。
而如果實現過程中,缺乏對於系統良好的認識和整理,希望“隨便搞搞,搞出來再整理“,這種在小型情況下是ok的,但是大型系統下,即便思維保持清晰,但是龐大的系統缺乏整理,而造成非常的複雜,很多東西由於前後設計的不一致,導致是處於一個不合理的複雜情況–需要你去死記。
這樣造成的結果就是,即便你對於整體系統的設計非常的清晰,但是在編程過程中,由於系統的一定的混亂,讓你沒法整個過程非常清晰的,心如止水的進行,整個的過程,磕磕絆絆,讓人疲憊不堪。
所以在後半段,就停下來改變了策略,先做充分的整理,把不需要的部分去除,然後把代碼整理到完全準備好來做新代碼的實現,才去做新的實現,這樣反而是最快的,寫起來也愉快迅捷。
運行效率

處理效率,常規的基本做法是profile熱點,以及根據遊戲的情況進行feature的關閉。
但是這個能做的事情是非常有限的,如果想做進一步提升效能,接近效能的極限,必須要做的就是:
- 對於每一個模組有充分的理解
- 可以做到快速的反覆嘗試迭代
處理效能熱點,在最佳化早期是一個非常高效的做法,準確來講,熱點處理是”在有水分的情況下,高效提升效能“的方法。
但是在追求極限效能方面,熱點最佳化還是不夠,某一個模組的效能消耗是不是超過了它應該有的,以及一個排名10名開外的模組其實是不需要高頻啟動並執行等等,這些都是熱點處理不能解決的。
在對於程式有充分瞭解,就可以進行更徹底的調整,把大量的運行做並行,低頻執行或者直接最佳化掉。
實踐中看下來,這樣的處理會把程式的效能帶到一個新的台階。

這個道理可以說是知易行難,難就難在,對一個超大系統(比如對於《天涯明月刀》來說,就是整個用戶端,覆蓋幾十萬行的代碼),如何做到充分理解,如何做到容易的徹底的修改最佳化。

所以關鍵點又回到複雜度,只有程式的複雜度得到最好的控制,才能較好的做這個工作。
這個後來在實踐中,最佳化過程中,大約一半時間是在做代碼的調整和重構,代碼合理就會讓最佳化更加的可行和高效。

複雜度控制的方法與實踐
實踐下來,複雜度控制的能力在我看來可以從三個方面來拆解:渴望,目標與時間積累。
渴望:
首先最有效方式就是去承擔實際的,要覆蓋非常大範疇的開發工作單位,這種情況下,你就會對於複雜度有切膚之痛,你就會非常真切的瞭解到複雜度是什麼,什麼是重要的,讓你抓狂的,什麼只是虛張聲勢,無足輕重的,有了非常充分的渴望,那麼後面的積累和實踐就容易多了。
目標:
方法和實踐會是非常的多,但是目標卻簡單很多,就是能夠始終保持對於整個系統,在代碼層級非常的清晰。在開發設計和做決定的時候,能有心如止水般的順暢即可。所以一定程度上,可以說複雜度控制還是比較主觀的,也很看火候的。比如有時候項目本來就比較小,即便複雜度控制不是很好,但是也非常的清晰,hold住,那就可以把更多的精力放在其他方面。
方法:
個人實踐中,這幾個方面可以注意下:
- 任務切分+代碼整理:在較小型的任務結束的時候,就開始做小規模的代碼整理,始終保持代碼是乾淨的
- 模式+自然:積累更多的模式,比如一大片的代碼,其實就是做了pool的事情,那麼這一大片的複雜度就是一個詞:pool。讓所有的東西都更加自然,符合編程的優秀實踐,這樣需要你記和注意的東西就很少,那麼它就是一個很低的複雜度。
比如下面這個代碼:

int a[5];for(int i=0; i<5; i++){    printf("%d",a[5]);}

這個在實際程式中就不是一個好的實踐,在看到這片代碼的時候,應該本能的注意到a[5]如果它的大小變化了怎麼辦,就會出現for的訪問越界的可能。

#define ARRAY_NUM(a) (sizeof(a)/sizeof(a[0]))int a[5];for(int i=0; i<ARRAY_NUM(a);i++){     printf("%d",a[i]);}

那麼再次看到這樣的代碼的時候,就會比較放心,一路就過去了,那麼這個就可以認為是複雜度比較低的(需要注意的或者刻意要記的東西少)。
所以保持一個總結積累就變得非常重要,對於編程模式或者演算法越來越多的積累,那麼在開發和思考的時候,就可以以更高的維度去做,那麼對於壓縮複雜度,提升思維速度和品質就非常的重要了。
並且,在這個層面上看,盡量返璞歸真的編程風格是一個更加有力的編程風格。

good for the programmer’s soul

“Low-level programming is good for the programmer’s soul.” - John Carmack

對於卡神的這句話,無比的贊同,做底層代碼實現,對硬體和系統有透徹的理解,對於程式員去清晰的理解整個程式如何啟動並執行至關重要,你就會更好的以底層的思維去思考。
同樣的道理,也可以用於高層的複雜度控制上面,更多的優秀的編程實踐,更好的理解要做的事情,理解系統本身,最後達到一個最簡潔的實現,整個設計和實現的過程,可以讓人進入心如止水的狀態,同樣的”good for the programmer’s soul“

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

程式的核心--複雜度

聯繫我們

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