Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Don't speculate, benchmark:</p> <p><strong>edit:</strong> I added my own matrix implementation using the optimized multiplication functions mentioned in my other answer. This resulted in a major speedup, but even the vanilla O(n^3) implementation of matrix multiplication with loops was faster than the Strassen algorithm.</p> <pre><code>&lt;pre&gt;&lt;script&gt; var fib = {}; (function() { var sqrt_5 = Math.sqrt(5), phi = (1 + sqrt_5) / 2; fib.round = function(n) { return Math.floor(Math.pow(phi, n) / sqrt_5 + 0.5); }; })(); (function() { fib.loop = function(n) { var i = 0, j = 1; while(n--) { var tmp = i; i = j; j += tmp; } return i; }; })(); (function () { var cache = [0, 1]; fib.loop_cached = function(n) { if(n &gt;= cache.length) { for(var i = cache.length; i &lt;= n; ++i) cache[i] = cache[i - 1] + cache[i - 2]; } return cache[n]; }; })(); (function() { //Fibonacci sequence generator in JS //Cobbled together by Salty var m; var odd = [[1,1],[1,0]]; function matrix(a,b) { /* Matrix multiplication Strassen Algorithm Only works with 2x2 matrices. */ var c=[[0,0],[0,0]]; var m1=(a[0][0]+a[1][1])*(b[0][0]+b[1][1]); var m2=(a[1][0]+a[1][1])*b[0][0]; var m3=a[0][0]*(b[0][1]-b[1][1]); var m4=a[1][1]*(b[1][0]-b[0][0]); var m5=(a[0][0]+a[0][1])*b[1][1]; var m6=(a[1][0]-a[0][0])*(b[0][0]+b[0][1]); var m7=(a[0][1]-a[1][1])*(b[1][0]+b[1][1]); c[0][0]=m1+m4-m5+m7; c[0][1]=m3+m5; c[1][0]=m2+m4; c[1][1]=m1-m2+m3+m6; return c; } function mat(n) { if(n &gt; 1) { mat(n/2); m = matrix(m,m); } m = (n%2&lt;1) ? m : matrix(m,odd); } fib.matrix = function(n) { m = [[1,0],[0,1]]; mat(n-1); return m[0][0]; }; })(); (function() { var a; function square() { var a00 = a[0][0], a01 = a[0][1], a10 = a[1][0], a11 = a[1][1]; var a10_x_a01 = a10 * a01, a00_p_a11 = a00 + a11; a[0][0] = a10_x_a01 + a00 * a00; a[0][1] = a00_p_a11 * a01; a[1][0] = a00_p_a11 * a10; a[1][1] = a10_x_a01 + a11 * a11; } function powPlusPlus() { var a01 = a[0][1], a11 = a[1][1]; a[0][1] = a[0][0]; a[1][1] = a[1][0]; a[0][0] += a01; a[1][0] += a11; } function compute(n) { if(n &gt; 1) { compute(n &gt;&gt; 1); square(); if(n &amp; 1) powPlusPlus(); } } fib.matrix_optimised = function(n) { if(n == 0) return 0; a = [[1, 1], [1, 0]]; compute(n - 1); return a[0][0]; }; })(); (function() { var cache = {}; cache[0] = [[1, 0], [0, 1]]; cache[1] = [[1, 1], [1, 0]]; function mult(a, b) { return [ [a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]], [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]] ]; } function compute(n) { if(!cache[n]) { var n_2 = n &gt;&gt; 1; compute(n_2); cache[n] = mult(cache[n_2], cache[n_2]); if(n &amp; 1) cache[n] = mult(cache[1], cache[n]); } } fib.matrix_cached = function(n) { if(n == 0) return 0; compute(--n); return cache[n][0][0]; }; })(); function test(name, func, n, count) { var value; var start = Number(new Date); while(count--) value = func(n); var end = Number(new Date); return 'fib.' + name + '(' + n + ') = ' + value + ' [' + (end - start) + 'ms]'; } for(var func in fib) document.writeln(test(func, fib[func], 1450, 10000)); &lt;/script&gt;&lt;/pre&gt; </code></pre> <p>yields</p> <pre><code>fib.round(1450) = 4.8149675025003456e+302 [20ms] fib.loop(1450) = 4.81496750250011e+302 [4035ms] fib.loop_cached(1450) = 4.81496750250011e+302 [8ms] fib.matrix(1450) = 4.814967502500118e+302 [2201ms] fib.matrix_optimised(1450) = 4.814967502500113e+302 [585ms] fib.matrix_cached(1450) = 4.814967502500113e+302 [12ms] </code></pre> <p>Your algorithm is nearly as bad as uncached looping. Caching is your best bet, closely followed by the rounding algorithm - which yields incorrect results for big <code>n</code> (as does your matrix algorithm).</p> <p>For smaller <code>n</code>, your algorithm performs even worse than everything else:</p> <pre><code>fib.round(100) = 354224848179263100000 [20ms] fib.loop(100) = 354224848179262000000 [248ms] fib.loop_cached(100) = 354224848179262000000 [6ms] fib.matrix(100) = 354224848179261900000 [1911ms] fib.matrix_optimised(100) = 354224848179261900000 [380ms] fib.matrix_cached(100) = 354224848179261900000 [12ms] </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload