プロメモグラム

誰が見てもわかるような文章を目指す

メモ化とline_profilerによる計測

アルゴリズムの勉強などをあまりしていなかったので,メモ化という言葉は就活なんかでの技術試験で知るのが初めてだった.
メモ化自体はそこまで難しいことではなく,何度も同じ計算をしないで,一度計算したものをうまく保存することで計算結果を再利用するというものである.

例として,フィボナッチ数列がよく使われる.
フィボナッチ数列は,fib(n) = fib(n-1) + fib(n-2)で定義されるため,fib(k)が何度も呼び出されることになる.
ここで,メモ化を用いることで,一度計算したfib(k)を保存し,再利用する.

これを,時間計測ツールであるline_profilerを用いて,計測した.

# 通常のフィボナッチ数列
def normal_fib(n):
    if n == 0 or n == 1 :
        return n
    else:
        return normal_fib(n-1) + normal_fib(n-2)

# メモするフィボナッチ数列
memo = [0 for x in range(100)]
def memo_fib(n):
    if n < 2 :
        return n
    elif memo[n] != 0:
        return memo[n]
    else:
        memo[n] = memo_fib(n-1) + memo_fib(n-2)
        return memo[n]

@profile
def main():
    print(memo_fib(20))
    print(normal_fib(20))

if __name__ == '__main__':
    print("Memoization!!!")
    main()
    print(memo)

fib(20)で比較した出力結果は以下のよう.

Memoization!!!
6765
6765
[0, 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Wrote profile results to memo.py.lprof
Timer unit: 1e-06 s

Total time: 0.015669 s
File: memo.py
Function: main at line 19

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    19                                           @profile
    20                                           def main():
    21         1         51.0     51.0      0.3      print(memo_fib(20))
    22         1      15618.0  15618.0     99.7      print(normal_fib(20))