【高速化】abs()関数を使うべきか
Posted on 2013年11月14日(木) 23:13
絶対値を求めるC言語の関数はabs() です。
なんとなく関数呼び出しのコストがもったいない気がして、
int a = b >0 ? b : -b;
みたいな書き方を見かけることがあります。
(というか意識せずに自分でも書いていることが・・・)
ちょっと話は変わって、絶対値計算に条件分岐が必要だと思いますか?
答えは環境依存、、ということになりますが、大抵の環境では条件分岐不要です。
現代の多くの環境においてはabs()関数を使えば関数呼び出しはインライン展開された上に分岐なしの絶対値計算コードが出力されます。
だからあまり気にせずabs()を使ってOK。
VisualC++にてint a = abs(b);というプログラムをコンパイルした結果は以下のような感じになりました。たったの3命令、しかも分岐なし。
(EAXレジスタにbの値が入っている)
cdq xor eax,edx sub eax,edx
CDQが見慣れない感じですが、CDQ命令はEAXレジスタの符号をEDXレジスタのすべてのビット位置にコピーする便利命令です。
C言語風に書くと以下のような感じでしょうか。
a = (b ^ (b >> 31)) - (b >> 31);
結論。
標準関数は自分で再実装せず、ありがたくそのまま使え。