2013年8月6日火曜日

JavaScript、Cにおいて、掛け算、割り算でビット演算子(シフト演算子)を使うことが高速化に繋がるかの確認してみる。

きっかけ。

JavaScriptの場合。

ビット演算子の場合。(シフト演算子)

コード(BBEdit)

var a,
    start,
    t,
    result = "",
    max = parseInt($('#max_n').val(), 10);
a = 1;
start = new Date();
for (i = 0; i < max; i += 1) {
    a <<= 1;
    a >>= 1;
}
t = (new Date() - start) / 1000;
result += t + "秒\n";
$('#pre0').text(result);


そのままの場合。

コード(BBEdit)

var a,
    start,
    t,
    result = "",
    max = parseInt($('#max_n').val(), 10);
a = 1;
start = new Date();
for (i = 0; i < max; i += 1) {
    a *= 2;
    a /= 2;
}
t = (new Date() - start) / 1000;
result += t + "秒\n";
$('#pre1').text(result);


ローカルの環境で、Safari、Chrome、Firefox(いずれもMac版)で試したところ、結果はまちまちだったけど、何回か繰り返すと、平均的にはそのままの場合(ビット演算子を使わない場合)の方が速かった。(evalを使ってるから、その速度が遅くて、肝心の演算の速度の差があんまり無くなっちゃってるのかも…)ということで、シフト演算子を使っても高速化に役立ってない(むしろ、遅くなってる)から、ビット演算子は悪いパーツと確認できた。(高速化にならず、むしろ遅くなる理由は上記の本に書いてある。)

C言語の場合。

コードBBEdit

sample.c

#include <stdio.h>
#include <limits.h>

int main()
{
    int a = 1;
    int i;
    
    for (i = 0; i < INT_MAX; i++) {
        a <<= 1;
        a >>= 1;
    }
    
    return 0;
}

入出力結果(Terminal)

$ time ./a.out

real 0m18.350s
user 0m16.912s
sys 0m0.070s
$ time ./a.out

real 0m19.103s
user 0m18.143s
sys 0m0.064s
$

そのままの場合。

コードBBEdit

sample.c

#include <stdio.h>
#include <limits.h>

int main()
{
    int a = 1;
    int i;
    
    for (i = 0; i < INT_MAX; i++) {
        a *= 2;
        a /= 2;
    }
    
    return 0;
}

入出力結果(Terminal)

$ time ./a.out

real 0m18.371s
user 0m15.045s
sys 0m0.099s
$ time ./a.out

real 0m15.366s
user 0m14.258s
sys 0m0.071s
$

どちらもあんまり変わらない。(ビット演算子を使っても高速化にはあまり意味がないって考えていい結果かなぁ。)ということで、上記の本の通り、コンパイラが自動的に最適化、高速化してくれてるみたい。

0 コメント:

コメントを投稿