作者: StubbornLin (Victor) 看板: C_and_CPP 標題: Re: [問題] 程式的執行速度 時間: Sat Sep 3 18:01:30 2005 ※ 引述《qlight (...)》之銘言: : 請問一下 大大們 : 因為我的數值很大 變數必須用double來宣告才存放的下 : (其中包含 陣列也是宣告成 double) : 因此 我的程式好像跑的特別的慢... : 請問 有什麼改善的方法嗎? : 如果用好一點的機器跑會不會 有一些些的幫助? : thanks 關於程式執行的效能,最主要的關鍵,還是演算法和流程 當演算法流程都已經做得很好時,這時如果還要擠出更多的效能 就只能從一些小地方來加強 1.for回圈的遞增 for(int i=0;i<n;i++){ dosomething(); } 以這個例子來說i++應該改成++i 因為i++會多出一個暫時的變數 2.無限回圈 while(true){ dosomething(); } 以這樣的無限回圈來說,應該改成 for(;;){ dosomething(); } 以while(true)來說,應該每次回圈都會檢查一次條件,這是多餘的 3.回圈的判斷式盡量以變數先算完 for(int i=0;i<(int)pow(n,0.5f);++i){ dosomething(); } 以這樣的回圈來說,for一般會每跑完一圈,就重新計算一次pow(n.0.5f) 如果,這條件的值,沒有更動的必要,就先用一個變數,來存放結果 int end = (int)pow(n,0.5f); for(int i=0;i<end;++i){ dosomething(); } 4.能在回圈外完成的東西,盡量擺到回圈外 一個回圈,通常在越裡面執行的次數越多,所以 很多東西如果能夠擺到圈外的話,就盡量擺到圈外去 for(int i=0;i<n;++i){ for(int j=0;j<m;++j){ xxxx.... if( pow( pow(A,2)+pow(B,2) ,0.5f) == R){ dosomething(); }else{ doanotherthing(); } } } 以上,是假設圈內的動作,與判斷式無關 所以,判斷式在圈外就能完成,應該改成 for(int i=0;i<n;++i){ if( pow( pow(A,2)+pow(B,2) ,0.5f) == R){ for(int j=0;j<m;++j){ xxxx.... dosomething(); } }else{ for(int j=0;j<m;++j){ xxxx.... doanotherthing(); } } } 雖然說,幾乎同樣的程式碼被重複了兩次,但是換來的是省下好幾次的判斷 5.盡量避免使用* / 等等花時間的運算 + - 的運算 速度遠比 * / 快 所以,如果一個演算法是以+ -取代 * / 運算的話 效能通常都會比用*和/快很多 +比-快 而*又比/快 但是,以上情況,是在整數適用 當到了float等浮點運算時,情況相反 * /比 + - 快,所以,如果必需用浮點的話,請盡量使用* or / 6.乘上或除上2的次方,用<<和>>取代 當一個數乘上或除上二的次方,就可以用移位來做運算 其速度遠比直接用乘除速度來的跨 int SizeOfImage = (W*H)<<1; 這行,就等於 int SizeOfImage = W*H*2; 以及除法 int MidPoint = (X1+X2)>>1; 就等於 int MidPoint = (X1+X2)/2 2的次方是指 2 4 8 16 32 64 128....等數 只要是乘上或除上都適用,不過,當然,這也只適合整數 7.盡量運用Bit運算 有很多計算,其實都可以用Bit的運算完成,因為Bit運算比一般的運算 速度上快了很多 例如,奇數偶數的運算,直觀的做法,當然是求除以二的餘數 if(n%2 != 0){ // 奇數 }else{ // 偶數 } 但是,以Bit運算來判斷,我們知道,只要最後一個Bit 是1就是奇數,0就是偶數,於是,便可以利用這點來做運算 if(n&0x1){ // 奇數 }else{ // 偶數 } 以上,是我個人的經驗,目前想到這裡,有想到再補上 這些很多做法,雖然能多擠出些效能,但是同時也會讓程式碼可讀性降低 程式碼也會增加,所以,在擠效能的同時,如果程式碼不是只有你要看的 請加上一些注解,來說明這是在幹麻的,否則很多東西真的是很難看懂 雖然,有些東西編譯器可能會幫你做,但是,我認為要擠效能就要明確的去做 不能全部依賴編譯器,因為你不能保證每個人用的都是和你一樣的編譯器 一樣的參數設定 如果有其它做法,也請Po上來 -- VICTOR工作室 URL : http://www.kinmen.info/vic/ C/C++ Visual Basic 6.0 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.116.73.165 ※ 編輯: StubbornLin 來自: 59.116.73.165 (09/03 18:03)