国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

More Effective C++之效率

2019-11-17 05:48:09
字體:
來源:轉載
供稿:網友


  我懷疑一些人在C++軟件開發人員身上進行秘密的巴甫洛夫試驗,否則為什么當提到“效率”這個詞時,許多程序員都會流口水。(Scott Meyers真幽默 譯者注)  事實上,效率可不是一個開玩笑的事情。一個太大或太慢的程序它們的優點無論多么引人注目都不會為人們所接受。本來就應該這樣。軟件是用來幫助我們更好地工作,說運行速度慢才是更好的,說需要32MB內存的程序比僅僅需要16MB內存的程序好,說占用100MB磁盤空間的程序比僅僅占用50MB磁盤空間的程序好,這簡直是無稽之談。而且盡管有一些程序確是為了進行更復雜的運算才占用更多的時間和空間,但是對于許多程序來說只能歸咎于其糟糕的設計和馬虎的編程?! ≡谟肅++寫出高效地程序之前,必須熟悉到C++本身絕對與你所碰到的任何性能上的問題無關。假如想寫出一個高效的C++程序,你必須首先能寫出一個高效的程序。太多的開發人員都忽視了這個簡單的道理。是的,循環能夠被手工展開,移位操作(shift Operation)能夠替換乘法,但是假如你所使用的高層算法其內在效率很低,這些微調就不會有任何作用。當線性算法可用時你是否還用二次方程式算法?你是否一遍又一遍地計算重復的數值?假如是的話,可以毫不夸張地把你的程序比喻成一個二流的觀光勝地,即假如你有額外的時間,才值得去看一看。  本章的內容從兩個角度闡述效率的問題。第一是從語言獨立的角度,關注那些你能在任何語言里都能使用的東西。C++為它們提供了非凡吸引人的實現途徑,因為它對封裝的支持非常好,從而能夠用更好的算法與數據結構來替代低效的類實現,同時接口可以保持不變?! 〉诙顷P注C++語言本身。高性能的算法與數據結構雖然非常好,但假如實際編程中代碼實現得很粗糙,效率也會降低得相當多。潛在危害性最大的錯誤是既輕易犯又不輕易察覺的錯誤,瀕繁地構造和釋放大量的對象就是一種這樣的錯誤。過多的對象構造和對象釋放對于你的程序性能來說就象是在大出血,在每次建立和釋放不需要的對象的過程中,寶貴的時間就這么流走了。這個問題在C++程序中很普遍,我將用四個條款來說明這些對象從哪里來的,在不影響程序代碼正確性的基礎上如何消除它們?! 〗⒋罅康膶ο蟛粫钩绦蜃兇蠖粫蛊溥\行速度變慢。還有其它一些影響性能提高的因素,包括程序庫的選擇和語言特性的實現(implementations of language features)。在下面的條款中我也將涉及?! ≡趯W習了本章內容以后,你將熟悉能夠提高程序性能的幾個原則,這些原則可以適用于你所寫的任何程序。你將知道如何準確地防止在你的軟件里出現不需要的對象,并且對編譯器生成可執行代碼的行為有著敏銳的感覺?! ∷自捳f有備無患(forewarned is forearmed)。所以把下面的內容想成是戰斗前的預備?! ?STRONG>牢記80-20準則(80-20 rule)  80-20準則說的是大約20%的代碼使用了80%的程序資源;大約20%的代碼耗用了大約80%的運行時間;大約20%的代碼使用了80%的內存;大約20%的代碼執行80%的磁盤訪問;80%的維護投入于大約20%的代碼上;通過無數臺機器、操作系統和應用程序上的實驗這條準則已經被再三地驗證過。80-20準則不只是一條好記的慣用語,它更是一條有關系統性能的指導方針,它有著廣泛的適用性和堅實的實驗基礎?! ‘斚氲?0-20準則時,不要在具體數字上糾纏不清,一些人喜歡更嚴格的90-10準則,而且也有一些試驗證據支持它。不管準確地數字是多少,基本的觀點是一樣的:軟件整體的性能取決于代碼組成中的一小部分?! ‘敵绦騿T力爭最大化提升軟件的性能時,80-20準則既簡化了你的工作又使你的工作變得復雜。一方面80-20準則表示大多數時間你能夠編寫性能一般的代碼,因為80%的時間里這些代碼的效率不會影響到整個系統的性能,這會減少一些你的工作壓力。而另一方面這條準則也表示假如你的軟件出現了性能問題,你將面臨一個困難的工作,因為你不僅必須找到導致問題的那一小塊代碼的位置,還必須尋找方法提高它們的性能。這些任務中最困難的一般是找到系統瓶頸。基本上有兩個不同的方法用來尋找:大多數人用的方法和正確的方法。  大多數人尋找瓶頸的方法就是猜。通過經驗、直覺、算命紙牌、顯靈板、傳聞或者其它更荒唐的東西,一個又一個程序員一本正經地宣稱程序的性能問題已被找到,因為網絡的延遲,不正確的內存分配,編譯器沒有進行足夠的優化或者一些笨蛋主管拒絕在要害的循環里使用匯編語句。這些評估總是以一種帶有嘲笑的盛氣凌人的架式發布出來,通常這些嘲笑者和他們的預言都是錯誤的。  大多數程序員在他們程序性能特征上的直覺都是錯誤的,因為程序性能特征往往不能靠直覺來確定。結果為提高程序各部分的效率而傾注了大量的精力,但是對程序的整體行為沒有顯著的影響。例如在程序里加入能夠最小化計算量的奇異算法和數據結構,但是假如程序的性能限制主要在I/O上(I/O-bound)那么就絲毫起不到作用。采用I/O性能強勁的程序庫代替編譯器本身附加的程序庫(參見條款23),假如程序的性能瓶頸主要在CPU上(CPU-bound),這種方法也不會起什么作用?! ≡谶@種情況下,面對運行速度緩慢或占用過多內存的程序,你該如何做呢?80-20準則的含義是胡亂地提高一部分程序的效率不可能有很大幫助。程序性能特征往往不能靠直覺確定,這個事實意味著試圖猜出性能瓶頸不可能比胡亂地提高一部分程序的效率這種方法好到哪里去。那么會后什么結果呢?  結果是用經驗識別程序20%的部分只會導致你心痛。正確的方法是用PRofiler程序識別出令人討厭的程序的20%部分。不是所有的工作都讓profiler去做。你想讓它去直接地測量你感愛好的資源。例如假如程序太緩慢,你想讓profiler告訴你程序的各個部分都耗費了多少時間。然后你關注那些局部效率能夠被極大提高的地方,這也將會很大地提高整體的效率。
  profiler告訴你每條語句執行了多少次或各函數被調用了多少次,這是一個作用有限的工具。從提高性能的觀點來看,你不用關心一條語句或一個函數被調用了多少次。究竟很少碰到用戶或程序庫的調用者抱怨執行了太多的語句或調用了太多的函數。假如軟件足夠快,沒有人關心有多少語句被執行,假如程序運行過慢,不會有人關心語句有多么的少。他們所關心的是他們厭惡等待,假如你的程序讓他們等待,他們也會厭惡你。  不過知道語句執行或函數調用的頻繁程度,有時能幫助你洞察軟件內部的行為。例如假如你建立了100個某種類型的對象,會發現你調用該類的構造函數有上千次,這個信息無疑是有價值的。而且語句和函數的調用次數能間接地幫助你理解不能直接測量的軟件行為。例如假如你不能直接測量動態內存的使用,知道內存分配函數和內存釋函數的調用頻率也是有幫助的。(也就是,operators new, new[], delete, and delete[]—參見條款8)  當然即使最好的profiler也是受其處理的數據所影響。假如用缺乏代表性的數據profile你的程序,你就不能抱怨profiler會導致你優化程序的那80%的部分,從而不會對程序通常的性能有什么影響。記住profiler僅能夠告訴你在某一次運行(或某幾次運行)時一個程序運行情況,所以假如你用不具有代表性的輸入數據profile一個程序,那你所進行的profile也沒有代表型。相反這樣做很可能導致你去優化不常用的軟件行為,而在軟件的常用領域,則對軟件整體的效率起相反作用(即效率下降)?! 》乐惯@種不正確的結果,最好的方法是用盡可能多的數據profile你的軟件。此外,你必須確保每組數據在客戶(或至少是最重要的客戶)如何使用軟件的方面能有代表性。通常獲取有代表性的數據是很輕易的,因為許多客戶都愿意讓你用他們的數據進行profile。究竟你是為了他們需求而優化軟件。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 西吉县| 江阴市| 靖宇县| 海晏县| 巩留县| 义乌市| 大渡口区| 博白县| 肥东县| 禄劝| 阿拉善左旗| 翼城县| 山西省| 瓦房店市| 宿松县| 永济市| 肃南| 武夷山市| 都昌县| 棋牌| 彭阳县| 永清县| 玉环县| 靖西县| 天水市| 彭山县| 普兰县| 和顺县| 互助| 扎赉特旗| 上蔡县| 新野县| 峨眉山市| 景宁| 砚山县| 天台县| 天台县| 湘潭市| 当雄县| 青龙| 汽车|