2013-02-07 46 views
1

我試圖包含斐波那契內部的備忘錄字典,因爲我試圖醃製函數。然而,在我的測試中,似乎嵌套函數顯着較慢,但我沒有看到這與其他版本的斐波那契只有當我使用memoized函數。爲什麼嵌套函數比unnested版本慢得多?

我所有的測試:https://gist.github.com/dasickis/4733353

#!/usr/bin/env python 

memo = {0: 0, 1: 1} 

# Contract: [int > 0] -> [int > 0] 
def fibonacci(n): 
    """ Return the `x`th number in the fibonacci series. """ 
    if not n in memo: 
     memo[n] = fibonacci(n - 1) + fibonacci(n - 2) 
    return memo[n] 

#--------------------------# 

# Contract: [int > 0] -> [int > 0] 
def fibonacci_nested(n): 
    memo = {0: 0, 1: 1} 

    def fib(n): 
     """ Return the `x`th number in the fibonacci series. """ 
     if not n in memo: 
      memo[n] = fib(n - 1) + fib(n - 2) 
     return memo[n] 

    return fib(n) 

#--------------------------# 

import timeit 
stmt = "assert fib(20) == 6765" 

print "fibonacci" 
print timeit.timeit(stmt, setup="from __main__ import fibonacci as fib") 
print 

print "fibonacci_nested" 
print timeit.timeit(stmt, setup="from __main__ import fibonacci_nested as fib") 

輸出:

fibonacci 
0.263559103012 

fibonacci_nested 
11.4014730453 
+2

我希望你仔細閱讀[文檔](http://docs.python.org/2/library/pickle.html#what-c​​an-be-pickled-and-unpickled)關於函數和類是如何「醃」。 「請注意,函數(內置的和用戶定義的)由」完全限定的「名稱引用而不是值,這意味着只有函數名稱被pickle,以及定義函數的模塊的名稱。這個函數的代碼和它的任何函數屬性都不會被pickle,因此這個定義模塊必須可以在unpickling環境中導入,並且這個模塊必須包含這個命名對象「 – Bakuriu

回答

8

您不乾淨運行給予版本之間的memo詞典沒有築巢不公平的優勢。第一次timeit運行fib它將填充memo字典,然後後續運行重新使用它。

嵌套函數每次都設置一個新的空的memo

+0

!非常感謝! – prafulfillment

相關問題