「匯編最快」→「C 接近匯編」→「C++ 比 C 慢」→「托管語言最慢」
這條鄙視鏈建立在「封裝損失性能」的直覺上,但現代編譯器與 CPU 微架構已打破此假設。
// 版本 A
int sum = 0;
for (int i = 0; i < 100; i++) sum += array[i];
// 版本 B (手動展開)
int sum1 = 0, sum2 = 0;
for (int i = 0; i < 100; i += 2) {
sum1 += array[i];
sum2 += array[i + 1];
}
sum = sum1 + sum2;
版本 B 更快:兩條獨立加法鏈 → CPU 可亂序並行執行;分支預測失敗懲罰減半。但現代編譯器 -O2/-O3 會自動完成此優化,手寫匯編反而阻礙編譯器進一步優化(如向量化)。
// 有分支版
if (eax < 0) eax = -eax;
// 無分支匯編版 (CDQ 指令技巧)
cdq // 符號擴展 EAX → EDX (0 或 -1)
xor eax, edx // 取反 (若負數)
sub eax, edx // +1 (若負數,因 EDX=-1,減 -1 即 +1)
消除條件分支 → 避免分支預測失敗。但編譯器內建此模式識別,abs() 直接生成最優指令序列。
| 維度 | 手寫匯編 | 現代編譯器 (LLVM/GCC/MSVC/JIT) |
|---|---|---|
| 指令調度 | 人工固定 | 基於 CPU 微架構模型自動調度 |
| 寄存器分配 | 人工管理 | 圖著色算法全局最優 |
| 向量化 | 極難手寫 | 自動 SIMD (AVX2/NEON/SVE) |
| 跨函數優化 | 幾乎不可能 | LTO / PGO / 內聯全局優化 |
| 可維護性 | 極低 | 高級語言可讀、可重構 |
CPUID、RDTSC、CLFLUSH、PAUSE)// 消除除法 (編譯器不敢自動優化:無法證明分母非負)
if (desiredWidth * originalHeight < desiredHeight * originalWidth) // 用乘法代替除法
// 向編譯器提供證明
[Assume(originalWidth > 0)] // 契約/斷言輔助編譯器優化
// 或 C# 8.0+ 非空引用類型、Code Contracts
匯編優化在現代工程中邊際收益極低、維護成本極高。真正的效能杠桿在:算法複雜度 → 數據結構 → 內存訪問模式 → 編譯器友好寫法 → PGO 引導優化。寫清晰、可驗證、符合現代 C++/C#/Rust 慣用語的代碼,讓編譯器為你做微觀優化,才是正道。