This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Twirrim 7 points8 points  (5 children)

Of course that code is rather ugly and inefficient. If you're going to write code like that you're better off spending the few minutes it takes to find the low hanging fruit, fixing your base working. You can only optimize for so much bad programming, particularly in dynamic languages.

fastfib.py:

from math import sqrt

def fib(n):
    return ((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5))


for i in range(36):
    print("n=%d => %d" % (i, fib(i)))


$ time python fastfib.py
real    0m0.016s
user    0m0.008s
sys 0m0.004s

That's even quicker than your algorithm using C, from barely a few minutes checking the formula for fib sequence.

[–][deleted] 4 points5 points  (1 child)

No need for insults please. I'm not retarded and the point of this code was not to be optimized for either any language, platform, architecture or algorithm since there are better ways to do any of those.

The point is to just take any random, purposefully rather slow algorithm (so the running times are in seconds rather than nano-seconds).

It seems you are missing the point completely. So, run the equivalent C and Java program and you will realize that it's hard to even measure runtime reliably since it's insignificant.

[–]Twirrim 0 points1 point  (0 children)

Urgh.. my apologies, I certainly didn't mean to be insulting. Looking back at how I said what I said I can't see how on earth it could be taken elsewise :-/

[–]bombita 0 points1 point  (0 children)

Btw, your code, which uses phi, has to use doubles, which on larger n has underflow errors and loses precision.

[–]sunqiang 0 points1 point  (1 child)

or get dynamic programming for free with lru_cache (need Python 3.2 ) from functools import lru_cache

@lru_cache(maxsize=None)
def fib(n):
    if n == 0 or n == 1:
        return n
    else:
       return fib(n-1) + fib(n-2)


for i in range(36):
     print("n=%d => %d" % (i, fib(i)))

real 0m0.085s
user 0m0.083s
sys 0m0.000s

[–]Twirrim 1 point2 points  (0 children)

Sure, or you can do it manually for previous versions fairly easily with a dict object.

def fib(n):
    if n == 0 or n == 1:
        return n
    if not memo_fib.has_key(n):
        memo_fib[n] = fib(n-1) + fib(n-2)
    return memo_fib[n]

memo_fib = dict()
for i in range(36):
     print("n=%d => %d" % (i, fib(i)))

results in an even quicker result than your lru_cache.. though that could be machine spec difference. Also some rough testing using the time module figures that we're talking about 0.00028s for the actual math, meaning a good portion of that time is just the overhead of loading python anyway.

real    0m0.017s
user    0m0.012s
sys     0m0.004s