多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > 綜合技術(shù) > 代碼優(yōu)化概要

代碼優(yōu)化概要

來源:程序員人生   發(fā)布時(shí)間:2014-06-10 10:20:52 閱讀次數(shù):3495次

我編寫程序至今有35年了,我做了很多關(guān)于程序執(zhí)行速度方面優(yōu)化的工(一個(gè)示例),我也看過其它人做的優(yōu)化。我發(fā)現(xiàn)有兩個(gè)最基本的優(yōu)化技術(shù)總是被人所忽略。

注意,這兩個(gè)技術(shù)并不是避免時(shí)機(jī)不成熟的優(yōu)化。并不是把冒泡排序變成快速排序(算法優(yōu)化)。也不是語言或是編譯器的優(yōu)化。也不是把 i*4寫成i<<2 i*4的優(yōu)化。

這兩個(gè)技術(shù)是:

  1. 使用 一個(gè)profiler。
  2. 查看程序執(zhí)行時(shí)的匯編碼。

使用這兩個(gè)技術(shù)的人將會(huì)成功地寫出運(yùn)行快的代碼,不會(huì)使用這兩個(gè)技術(shù)的人則不行。下面讓我為你細(xì)細(xì)道來。

使用一個(gè) Profiler

我們知道,程序運(yùn)行時(shí)的90%的時(shí)間是用在了10%的代碼上。我發(fā)現(xiàn)這并不準(zhǔn)確。一次又一次地,我發(fā)現(xiàn),幾乎所有的程序會(huì)在1%的代碼上花了99%的運(yùn)行時(shí)間。但是,是哪個(gè)1%?一個(gè)好的Profiler可以告訴你這個(gè)答案。就算我們需要使用100個(gè)小時(shí)在這1%的代碼上進(jìn)行優(yōu)化,也比使用100個(gè)小時(shí)在其它99%的代碼上優(yōu)化產(chǎn)生的效益要高得多得多。

問題是什么?人們不用profiler?不是。我工作過的一個(gè)地方使用了一個(gè)華麗而奢侈的Profiler,但是購買這個(gè)Profiler后,它的包裝3年還是那么的暫新。為什么人們不用?我真的不知道。有一次,我和我的同事去了一個(gè)負(fù)載過大的交易所,我同事堅(jiān)持說他知道哪里是瓶頸,畢竟,他是一個(gè)很有經(jīng)驗(yàn)的專家。最終,我把我的Profiler在他的項(xiàng)目上運(yùn)行了一下,我們發(fā)現(xiàn)那個(gè)瓶頸完全在一個(gè)意想不到的地方。

就像是賽車一樣。團(tuán)隊(duì)是贏在傳感器和日志上,這些東西提供了所有的一切。你可以調(diào)整一下賽車手的褲子以讓其在比賽過程中更舒服,但是這不會(huì)讓你贏得比賽,也不會(huì)讓你更有競(jìng)爭(zhēng)力。如果你不知道你的速度上不去是因?yàn)橐妗⑴艢庋b置、空體動(dòng)力學(xué)、輪胎氣壓,或是賽車手,那么你將無法獲勝。編程為什么會(huì)不同呢?只要沒有測(cè)量,你就永遠(yuǎn)無法進(jìn)步。

這個(gè)世界上有太多可以使用的Profiler了。隨便找一個(gè)你就可以看到你的函數(shù)的調(diào)用層次,調(diào)用的次數(shù),以前每條代碼的時(shí)間分解表(甚至可以到匯編級(jí))。我看過太多的程序員回避使用Profiler,而是把時(shí)間花在那些無用的,錯(cuò)誤的方向上的“優(yōu)化”,而被其競(jìng)爭(zhēng)對(duì)手所羞辱。(譯者陳皓注:使用Profiler時(shí),重點(diǎn)需要關(guān)注:1)花時(shí)間多的函數(shù)以優(yōu)化其算法,2)調(diào)用次數(shù)巨多的函數(shù)——如果一個(gè)函數(shù)每秒被調(diào)用300K次,你只需要優(yōu)化出0.001毫秒,那也是相當(dāng)大的優(yōu)化。這就是作者所謂的1%的代碼占用了99%的CPU時(shí)間)

查看匯編代碼

幾年前,我有一個(gè)同事,Mary Bailey,她在華盛頓大學(xué)教矯正代數(shù)(remedial algebra),有一次,她在黑板上寫下:

x + 3 = 5

然后問他的學(xué)生“求解x”,然后學(xué)生們不知道答案。于是她寫下:

__ + 3 = 5

然后,再問學(xué)生“填空”,所有的學(xué)生都可以回答了。未知數(shù)x就像是一個(gè)有魔法的字母讓大家都在想“x意味著代數(shù),而我沒有學(xué)過代數(shù),所以我就不知道這個(gè)怎么做”。

匯編程序就是編程世界的代數(shù)。如果某人問我“inline函數(shù)是否被編譯器展開了?”或是問我“如果我寫下i*4,編譯器會(huì)把其優(yōu)化為左移位操作嗎?”。這個(gè)時(shí)候,我都會(huì)建議他們看看編譯器的匯編碼。這樣的回答是不是很粗暴和無用?通常,在我這樣回答了提問者后,提問都通常都會(huì)說,對(duì)不起,我不知道什么是匯編!甚至C++的專家都會(huì)這么回答。

匯編語言是最簡(jiǎn)單的編程語言了(就算是和C++相比也是這樣的),如:

ADD ESI,x

就是(C風(fēng)格的代碼)

ESI += x;

而:

CALL foo

則是:

foo();

細(xì)節(jié)因?yàn)镃PU的種類而不同,但這就是其如何工作的。有時(shí)候,我們甚至都不需要細(xì)節(jié),只需要看看匯編碼的長(zhǎng)啥樣,然后和源代碼比一比,你就可以知道匯編代碼很多很多了。

那么,這又如何幫助代碼優(yōu)化?舉個(gè)例子,我?guī)啄昵罢J(rèn)識(shí)一個(gè)程序員認(rèn)為他應(yīng)該去發(fā)現(xiàn)一個(gè)新的更快的算法。他有一個(gè)benchmark來證明這個(gè)算法,并且其寫了一篇非常漂亮的文章關(guān)于他的這個(gè)算法。但是,有人看了一下其原來算法以及新算法的匯編,發(fā)現(xiàn)了他的改進(jìn)版本的算法允許其編譯器把兩個(gè)除法操作變成了一個(gè)。這和算法真的沒有什么關(guān)系。我們知道除法操作是一個(gè)很昂貴的操作,并且其還在一個(gè)內(nèi)嵌循環(huán)中,所以,他的改進(jìn)版的算法當(dāng)然要快一些。只需要在原來的算法上做一點(diǎn)點(diǎn)小的改動(dòng)——使用一個(gè)除法操作,那么其原來的算法將會(huì)和新的一樣快。而他的新發(fā)現(xiàn)什么也不是。

下一個(gè)例子,一個(gè)D用戶張貼了一個(gè) benchmark 來顯示 dmd (Digital Mars D 編譯器)在整型算法上的很糟糕,而ldc (LLVM D 編譯器) 就好很多了。對(duì)于這樣的結(jié)果,其相當(dāng)?shù)挠幸庖姟N已杆俚乜戳艘幌聟R編,發(fā)現(xiàn)兩個(gè)編譯器編譯出來相當(dāng)?shù)囊恢拢]有什么明顯的東西要對(duì)2:1這么大的不同而負(fù)責(zé)。但是我們看到有一個(gè)對(duì)long型整數(shù)的除法,這個(gè)除法調(diào)用了運(yùn)行庫。而這個(gè)庫成為消耗時(shí)間的殺手,其它所有的加減法都沒有速度上的影響。出乎意料地,benchmark 和算法代碼生成一點(diǎn)關(guān)系也沒有,完全就是long型整數(shù)的除法的問題。這暴露了在dmd的運(yùn)行庫中的long型除法的實(shí)現(xiàn)很差。修正后就可以提高速度。所以,這和編譯器沒有什么關(guān)系,但是如果不看匯編,你將無法發(fā)現(xiàn)這一切。

查看匯編代碼經(jīng)常會(huì)給你一些意想不到的東西讓你知道為什么程序的性能是那樣。一些意想不到的函數(shù)調(diào)用,預(yù)料不到的自傲,以及不應(yīng)該存在的東西,等等其實(shí)所有的一切。但也不需要成為一個(gè)匯編代碼的黑客才能干的事。

結(jié)論

如果你覺得需要程序有更好的執(zhí)行速度,那么,最基本的方法就是使用一個(gè)profiler和愿意去查看一下其匯編代碼以找到程序的瓶頸。只有找到了程序的瓶頸,此時(shí)才是真正在思考如何去改進(jìn)的時(shí)候,比如思考一個(gè)更好的算法,使用更快的語言優(yōu)化,等等。

常規(guī)的做法是制勝法寶是挑選一個(gè)最佳的算法而不是進(jìn)行微優(yōu)化。雖然這種做法是無可異議的,但是有兩件事情是學(xué)校沒有教給你而需要你重點(diǎn)注意的。第一個(gè)也是最重要的,如果你優(yōu)化的算法沒沒有參與到你程序性能中的算法,那么你優(yōu)化他只是在浪費(fèi)時(shí)間和精力,并且還轉(zhuǎn)移了你的注意力讓你錯(cuò)過了應(yīng)該要去優(yōu)化的部分。第二點(diǎn),算法的性能總和處理的數(shù)據(jù)密切相關(guān)的,就算是冒泡排序有那么多的笑柄,但是如果其處理的數(shù)據(jù)基本是排好序的,只有其中幾個(gè)數(shù)據(jù)是未排序的,那么冒泡排序也是所有排序算法里性能最好的。所以,擔(dān)心沒有使用好的算法而不去測(cè)量,只會(huì)浪費(fèi)時(shí)間,無論是你的還是計(jì)算機(jī)的。

就好像賽車零件的訂購速底是不會(huì)讓你更靠進(jìn)冠軍(就算是你正確安裝零件也不會(huì)),沒有Profiler,你不會(huì)知道問題在哪里,不去看匯編,你可能知道問題所在,但你往往不知道為什么。

Thanks to Bartosz Milewski, David Held, and Andrei Alexandrescu for their helpful comments on a draft of this.

本文譯自Dr. Dobb’s Blogger的Walter Bright寫的《Overlooked Essentials For Optimizing Code》

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 亚洲视频精品 | 国语高清精品一区二区三区 | 新午夜影院 | 国产精品福利视频一区二区三区 | 中文字幕在线观看2022 | 手机福利视频 | 亚洲综合第二页 | 国产淫视频 | 亚洲视频欧美 | 国产欧美精品一区二区三区四区 | 艹碰在线 | 亚洲欧美视屏 | 日韩欧美国产精品 | 日本欧美一区二区三区不卡视频 | 成人精品一区二区三区中文字幕 | 国产精品无码久久久久 | 日本欧美人xxxxx在线观看 | 一国产一级淫片a免费播放口 | 亚洲天堂久久精品成人 | 日本护士xxxx黑人巨大 | jux397在线三浦惠理子 | 亚洲一二四区性毛片1在线 亚洲一个色 | 激情视频在线观看网站 | 亚洲精品国产福利在线观看 | 日本xxxx黑人 | 亚洲成人黄色 | 午夜精品久久久久久91 | 亚洲第一视频在线观看 | 精品亚洲视频在线 | 亚洲欧美色欧另类欧 | 国产精品深夜福利免费观看 | 亚洲国产精品久久综合 | 国产中文99视频在线观看 | 最新国产在线观看福利 | 亚洲国产2017男人a天堂 | 黄色小说校园春色 | 簧片免费在线观看 | 亚洲高清免费 | 女性影院 | 亚洲播播| 久久亚洲精品久久久久 |