JavaScriptでフィボナッチ数を求めて実行速度を計測

はじめに

こんにちは、野村です。

今回は、いくつかの方法でフィボナッチ数を求めるスクリプトを書き、それぞれの実行速度を計測してみます。
スクリプトはJavaScriptを使います。

オーソドックスな再帰で書く

とても遅いです。
なので、この方法だけは33番目のフィボナッチ数を求めます。

'use strict';

const fib00 = (n)=>{
  return (n<2) ? n : fib00(n-2) + fib00(n-1);
}
console.time('timer00');
console.log(fib00(33));
console.timeEnd('timer00');

実行結果

3524578
timer00: 46.427ms

ループを使って書く

以下のものからは1000番目のフィボナッチ数を求めます。

'use strict';

const fib01 = (n)=>{
  let a = 0;
  let b = 1;
  let c;
  for(let i=0; i<n; i++){
    c = a;
    a = b;
    b = a+c;
  }
  return a;
}
console.time('timer01');
console.log(fib01(1000));
console.timeEnd('timer01');

実行結果

4.346655768693743e+208
timer01: 0.688ms

配列を使って書く

'use strict';

const fib02 = (n)=>{
  let a = Array(0,1);
  for(let i=2; i<=n; i++){
    a[i] = a[i-2] + a[i-1];
  }
  return a[n];
}
console.time('timer02');
console.log(fib02(1000));
console.timeEnd('timer02');

実行結果

4.346655768693743e+208
timer02: 0.772ms

足し上げていく方法

末尾再帰と似ているけど、方向が逆。
うまい表現ができないので「足し上げる」という言葉を勝手に作ってみた。

'use strict';

const fib03 = (n,a,b,i)=>{
  return (n===i) ? a : fib03(n,b,a+b,i+1);
}
console.time('timer03');
console.log(fib03(1000,0,1,0));
console.timeEnd('timer03');

実行結果

4.346655768693743e+208
timer03: 1.894ms

末尾再帰と同程度と考えていたけど、結構遅かった。

メモ化を使って書く

いまいち理解できた気がしないけど、メモ化ってこんな感じだと思う。

'use strict';

const fib04 = (n)=>{
  let memo = Array();
  const loop = (m)=>{
    if (m<2) return m;
    if (memo[m] !== undefined) return memo[m];
    return memo[m] = loop(m-2) + loop(m-1);
  }
  return loop(n);
}
console.time('timer04');
console.log(fib04(1000));
console.timeEnd('timer04');

実行結果

4.346655768693743e+208
timer04: 0.395ms

末尾再帰を使って書く

'use strict';

const fib05 = (n,a,b)=>{
  if (n==0) return 0;
  if (n==1) return b;
  return fib05(n-1,b,a+b);
}
console.time('timer05');
console.log(fib05(1000,0,1));
console.timeEnd('timer05');

実行結果

4.346655768693743e+208
timer05: 0.125ms

さすがに早い。

おわりに

以上、いくつかの方法でフィボナッチ数を求めるスクリプトを書き、それぞれの実行速度を計測してみました。

というわけで、今回はこれにて。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

野村 野村のプロフィール
メインPCはWindows10のVirtualBox上のFreeBSD。Linux/Unixの小ネタを求めて日々右往左往してたりする。twitterやってます⇒https://twitter.com/usr_sbin。Facebookもやってます⇒https://www.facebook.com/nomura.634