MoreEffectiveC++之效率

字號(hào):

我懷疑一些人在C++軟件開(kāi)發(fā)人員身上進(jìn)行秘密的巴甫洛夫試驗(yàn),否則為什么當(dāng)提到“效率”這個(gè)詞時(shí),許多程序員都會(huì)流口水。(Scott Meyers真幽默 譯者注)
    事實(shí)上,效率可不是一個(gè)開(kāi)玩笑的事情。一個(gè)太大或太慢的程序它們的優(yōu)點(diǎn)無(wú)論多么引人注目都不會(huì)為人們所接受。本來(lái)就應(yīng)該這樣。軟件是用來(lái)幫助我們更好地工作,說(shuō)運(yùn)行速度慢才是更好的,說(shuō)需要32MB內(nèi)存的程序比僅僅需要16MB內(nèi)存的程序好,說(shuō)占用100MB磁盤(pán)空間的程序比僅僅占用50MB磁盤(pán)空間的程序好,這簡(jiǎn)直是無(wú)稽之談。而且盡管有一些程序確是為了進(jìn)行更復(fù)雜的運(yùn)算才占用更多的時(shí)間和空間,但是對(duì)于許多程序來(lái)說(shuō)只能歸咎于其糟糕的設(shè)計(jì)和馬虎的編程。
    在用C++寫(xiě)出高效地程序之前,必須認(rèn)識(shí)到C++本身絕對(duì)與你所遇到的任何性能上的問(wèn)題無(wú)關(guān)。如果想寫(xiě)出一個(gè)高效的C++程序,你必須首先能寫(xiě)出一個(gè)高效的程序。太多的開(kāi)發(fā)人員都忽視了這個(gè)簡(jiǎn)單的道理。是的,循環(huán)能夠被手工展開(kāi),移位操作(shift operation)能夠替換乘法,但是如果你所使用的高層算法其內(nèi)在效率很低,這些微調(diào)就不會(huì)有任何作用。當(dāng)線性算法可用時(shí)你是否還用二次方程式算法?你是否一遍又一遍地計(jì)算重復(fù)的數(shù)值?如果是的話,可以毫不夸張地把你的程序比喻成一個(gè)二流的觀光勝地,即如果你有額外的時(shí)間,才值得去看一看。
    本章的內(nèi)容從兩個(gè)角度闡述效率的問(wèn)題。第一是從語(yǔ)言獨(dú)立的角度,關(guān)注那些你能在任何語(yǔ)言里都能使用的東西。C++為它們提供了特別吸引人的實(shí)現(xiàn)途徑,因?yàn)樗鼘?duì)封裝的支持非常好,從而能夠用更好的算法與數(shù)據(jù)結(jié)構(gòu)來(lái)替代低效的類實(shí)現(xiàn),同時(shí)接口可以保持不變。
    第二是關(guān)注C++語(yǔ)言本身。高性能的算法與數(shù)據(jù)結(jié)構(gòu)雖然非常好,但如果實(shí)際編程中代碼實(shí)現(xiàn)得很粗糙,效率也會(huì)降低得相當(dāng)多。潛在危害性的錯(cuò)誤是既容易犯又不容易察覺(jué)的錯(cuò)誤,瀕繁地構(gòu)造和釋放大量的對(duì)象就是一種這樣的錯(cuò)誤。過(guò)多的對(duì)象構(gòu)造和對(duì)象釋放對(duì)于你的程序性能來(lái)說(shuō)就象是在大出血,在每次建立和釋放不需要的對(duì)象的過(guò)程中,寶貴的時(shí)間就這么流走了。這個(gè)問(wèn)題在C++程序中很普遍,我將用四個(gè)條款來(lái)說(shuō)明這些對(duì)象從哪里來(lái)的,在不影響程序代碼正確性的基礎(chǔ)上如何消除它們。
    建立大量的對(duì)象不會(huì)使程序變大而只會(huì)使其運(yùn)行速度變慢。還有其它一些影響性能提高的因素,包括程序庫(kù)的選擇和語(yǔ)言特性的實(shí)現(xiàn)(implementations of language features)。在下面的條款中我也將涉及。
    在學(xué)習(xí)了本章內(nèi)容以后,你將熟悉能夠提高程序性能的幾個(gè)原則,這些原則可以適用于你所寫(xiě)的任何程序。你將知道如何準(zhǔn)確地防止在你的軟件里出現(xiàn)不需要的對(duì)象,并且對(duì)編譯器生成可執(zhí)行代碼的行為有著敏銳的感覺(jué)。
    俗話說(shuō)有備無(wú)患(forewarned is forearmed)。所以把下面的內(nèi)容想成是戰(zhàn)斗前的準(zhǔn)備。