C言語のdiv関数
C言語のdiv関数というものの存在を今日知りました。
商と余りを一度に求めるそうです。
#include <stdlib.h> int main() { int i, sum = 0; for (i=0; i<100000000; i++) { div_t d = div(5, 2); /* 5割る2の商と余りを求める */ sum += d.quot; sum += d.rem; } return 0; }
同等ものを「/」と「%」を使って書くと次のようになります。
#include <stdlib.h> int main() { int i, sum = 0; for (i=0; i<100000000; i++) { int q, r; q = 5 / 2; r = 5 % 2; sum += q; sum += r; } return 0; }
ついでに計測
$ time ./use_div real 0m2.327s user 0m2.313s sys 0m0.020s $ time ./use_operator real 0m0.897s user 0m0.891s sys 0m0.000s
div遅すぎ...
予想してましたが、やっぱり遅かった。
いまいちdivの存在意義が分かりません。
ちなみにCommon Lispではtruncateという関数が商と余りを多値で返します。
(defun div-test (n) (let ((ret 0)) (dotimes (i n ret) (setf ret (multiple-value-call #'+ ret (truncate 5 2))))))
(2011/07/13 追記)
このエントリへのスパムコメントがやたらと多いので、コメント欄を閉じます。
なにかコメントがある方は別のエントリにコメントを付けて下さい。
関数呼び出しと構造体をスタックに積むからですよね。
ものの本の解説によると、
大抵のCPUでは、同時に計算できるので、そのような最適化をするためだとか・
インライン化もしてくれなくちゃですね。
面白い現象ですが、ひょっとしてgccか何かでコンパイルしてませんか?
gccは通常、-O0付けて最適化なしでコンパイルしても定数畳み込みだけはやりますので、
下のCコードはただの足し算になっちゃいます。