童話王国 -覚書-

童話王国の生活をサポートする生産特化型計算ツール作者の気まぐれ開発日誌&キャラ育成日記。

FizzBuzz問題:実行速度も測ってみた[JavaScript]

2007-05-10 18:46:56 | 覚書
どうしてプログラマに・・・プログラムが書けないのか?

気になったのでやってみました。
答えはいくらでもあるのですが良く書く2通りの方法を試し、
実行速度を測ってみました。


-方法1-
s = "";
for(i=1; i<101; i++){
 // 15で割り切れる時
 if(i%15 == 0) {  //①
  s += "FizzBuzz";
 } // 5で割り切れる時
 else if(i%5 == 0) {
  s += "Buzz";
 } // 3で割り切れる時
 else if(i%3 == 0) {
  s += "Fizz";
 } // それ以外
 else {
  s += i;
 }
}

①if(i%3 == 0 && i%5 == 0) でも同じですが、
最小公倍数が「15」と判っているため処理の高速化を狙う。


-方法2-
s = "";
for(i=1; i<101; i++){
 t = "";
 if(i%3 == 0) {
  t = "Fizz";
 }

 if(i%5 == 0) {
  t += "Buzz";
 }

 if(t == "") {
  s += i;
 } else {
  s += t;
 }
}


-計測方法-
JavaScriptにて、

var now = new Date();
v_time = 50000;

上記方法1または方法2のソースの中の「i<101」→「i<v_time」に変更

var now2 = new Date();
alert(now2.getTime() - now.getTime());

とし、10回実行し開始と終了の差分を求めました。(単位はms)
(100回計測しろという話はなしで。IEかかりすぎ。)


-実行時間-

背景:黄→最短
背景:赤→最長

比較した結果、方法1が早い結果になりました。
理由として、方法2は必ず3回の比較があることが原因です。
方法1は最短比較は1回、最長比較は3回となります。


スーパーで3個の商品の中から1個を選ぶ時に、
「欲しくない物も必ず手に取り1個ずつどうしようかな?」(方法2)
とするより、
「1個ずつ手に取るけれど欲しい物が見つかったら次の棚を見に行く」(方法1)
のが早いですよね。


日常生活に例えず、実際の判定回数で表すと、

ループ数が100のとき
方法1のif判定は、274回
方法2のif判定は、300回

ループ数が49999のとき
方法1のif判定は、136,665回
方法2のif判定は、149,997回

となります。


実際には、方法1で書けるところは書くけれど
方法2で書かないといけないことが多いわけで。


で、処理部の最短を狙ってみましたが・・・

方法1→s="";for(i=1;i<101;i++)s+=i%15?i%5?i%3?i:"Fizz":"Buzz":"FizzBuzz";
方法2→s=a="";for(i=1;i<101;i++){t=i%3?a:"Fizz";t+=i%5?a:"Buzz";s+=t==a?i:t;}

うーんJavaScriptで56ってどうやるんだ・・・?
改行処理を無視しているのに60以上・・・


あ、自分の場合は最初に方法2が浮かび、
その後もっと早くならないかなーと考えて方法1に書き直す場合が殆どです。

で、書かずに方法1への変更を考えていると遅くなり、
だんだん嫌になってくるw


ところでOperaの実行速度が速いんですけど。
昔はJavaScript弱いって言われていたのにどこが変わったんだろ?

最新の画像もっと見る

3 コメント

コメント日が  古い順  |   新しい順
56文字できました (LiosK)
2008-03-16 00:53:13
for(i=0;i++<100;print(i%5?s||i:s+'Buzz'))s=i%3?'':'Fizz'
返信する
方法2はまだまだ縮まりますね ()
2011-10-05 19:23:16
for(i=0,a='';i++<100;print(t?t:i))t=i%3?a:"Fizz",t+=i%5?a:"Buzz";
返信する
えすけーぷされた ()
2011-10-05 19:27:05
for(i=0,a='';i++<100;print(t?t:i))t=i%3?a:"Fizz",t+=i%5?a:"Buzz"
返信する

コメントを投稿