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 追記)
このエントリへのスパムコメントがやたらと多いので、コメント欄を閉じます。
なにかコメントがある方は別のエントリにコメントを付けて下さい。

2 Responses to “C言語のdiv関数”

  1. BLUEPIXY より:

    関数呼び出しと構造体をスタックに積むからですよね。
    ものの本の解説によると、
    大抵のCPUでは、同時に計算できるので、そのような最適化をするためだとか・
    インライン化もしてくれなくちゃですね。

  2. nish より:

    面白い現象ですが、ひょっとしてgccか何かでコンパイルしてませんか?
    gccは通常、-O0付けて最適化なしでコンパイルしても定数畳み込みだけはやりますので、
    下のCコードはただの足し算になっちゃいます。