作者: 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)