首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

編寫高效C程序與代碼優化全攻略:從整型選擇到循環展開

     編輯:關於C

核心原則:權衡速度、空間與可讀性

優化目標:在嚴格內存限制(嵌入式/移動設備)下最大化速度。優化常增加代碼量,需謹慎選擇熱點路徑。

1. 數據類型優化

  • 優先用無符號整型:非負場景用unsigned int,部分CPU無符號運算更快。
  • 寄存器關鍵字:register unsigned int var;提示編譯器優先分配寄存器(現代編譯器多自動優化)。
  • 避免浮點運算:整型運算直接由CPU完成,浮點需协處理器/庫,慢數十倍。延後轉換,定點運算替代。

2. 除法與取模優化

  • 除法極慢(20-140周期)。能用乘法/移位替代除法:a/b > c → a > c*b(b>0且無溢出)。
  • 除數為2的冪次:編譯器自動優化為移位。無符號移位更快(邏輯右移),有符號需算術右移修正負數截斷差異。
  • 合併除法與取模:a/b + a%b編譯器可合併為單次除法指令。
  • 取模替換為條件判斷:x = (x+1)%60 → if (++x >= 60) x=0;(已知範圍內更快)。

3. 變量與內存訪問優化

  • 局部變量優於全局:全局變量不分配寄存器,須間接訪問。熱點循環中用局部變量緩存全局值,循環結束寫回。
  • 避免指針別名:編譯器不知指針是否指向同一地址,不敢優化。用restrict(C99)或局部變量緩存*ptr消除別名。
  • 指針鏈緩存:p->pos->x多次訪問 → Point3 *pos = p->pos; pos->x=...。
  • 結構體傳指針:避免大結構體壓棧拷貝,傳const Struct*。唯讀加const助編譯器優化。

4. 控制流優化

  • 簡化條件表達式:將關系運算分組,便於條件執行指令(如ARM的條件執行)。
  • 範圍檢查優化:(x>=min && x → (unsigned)(x-min) < (max-min)(單次比較)。
  • 利用零標誌位:if (x+y < 0)後緊跟ADD指令可省CMP,編譯器自動優化。
  • 惰性求值:if (a>10 && b=4)將最可能為false的條件前置。
  • switch優於if-else鏈:跳轉表O(1) vs 線性判斷。案例值稠密時用查找表更快(如字符串映射)。
  • 二分決策樹:有序條件構建平衡判斷樹,最壞比較次數log₂N。

5. 循環優化

  • 倒序循環:for(i=n; i--;) 或 for(i=n; i!=0; --i),終止條件測試i!=0比i快(隱含零標誌位)。
  • 循環融合:合併相同範圍的多個循環,減少循環開銷,提高指令緩存命中。
  • 函數內聯/循環內聯:將小函數調用移入循環體,或將循環移入函數,消除調用開銷。
  • 循環展開:手動展開小循環(固定次數)或分塊展開(動態次數,如每8次一塊+switch處理餘數),減少分支預測失敗與計數器更新。
  • 提前退出:搜索類循環找到目標即break,避免無效遍歷。

6. 函數設計優化

  • 函數短小精悍:利於寄存器分配與編譯器優化。
  • 參數≤4個:ARM等架構前4參數用寄存器傳遞,超過部分壓棧(雙倍內存訪問)。
  • 葉子函數:不調用其他函數,無需保存鏈接寄存器LR,極高效。熱點函數設計為葉子或__inline。
  • 內聯函數:__inline消除調用開銷,參數為常量時可進一步常量傳播優化。慎用於大函數/高頻調用(代碼膨脹)。

7. 查找表替代計算

  • sin/cos、偽隨機數、位計數等可預計算為表。精度換速度,嵌入式常用。
  • 合併相近運算為單表,減少存儲與訪問開銷。

8. 浮點運算優化

  • 除法慢於乘法2倍:x/3.0 → x*(1.0/3.0)(倒數編譯期計算)。
  • 優先用float而非double(精度足夠時),佔用更少寄存器/內存,運算更快。
  • 避免超越函數(sin/log等),由多項式逼近實現,極慢。查找表或CORDIC算法替代。
  • 手動簡化浮點表達式:編譯器不敢重排浮點運算(精度/結合律差異),如3*(x/3) ≠ x。
  • 定點運算替代:數值範圍小時,整數模擬小數,精度更高速度更快。

9. 綜合技巧清單

  • 以空間換時間:緩存熱點數據(sin表、隨機數池)。
  • 少用全局變量,文件內部變量加static。
  • 避免遞歸(調用開銷大),改迭代/顯式棧。
  • 一維數組快於多維(連續內存、索引計算簡單)。
  • #define宏替代極小函數(無調用開銷),注意副作用與類型安全。

參考資源

  • ARM: Writing Efficient C for ARM (DAI 0034A)
  • GNU C優化指南、Richard's C Optimization Page
  • Agner Fog's Optimization Manuals
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved