मैं रियल वर्ल्ड ओकैमल (आरडब्ल्यूओ) के अध्याय 8 में ज्ञापन पर अनुभाग को समझने की कोशिश कर रहा हूं। मुझे यह नहीं मिल रहा था, इसलिए मैंने ओकैमल कोड को पायथन में अनुवाद करने का निर्णय लिया। यह अभ्यास उपयोगी साबित हुआ, क्योंकि (1) मैंने अंततः समझ लिया कि आरडब्ल्यूओ क्या कह रहा था, और (2) मैंने कुछ तेज़ पायथन कोड लिखा जो काम करता है। हालांकि, पायथन कोड लिखने में, मैंने दो अलग-अलग तरीकों को याद करने की कोशिश की: एक बार एक रैपिंग फ़ंक्शन को सादा कॉल का उपयोग करके और एक बार पाइथन के सजावटी वाक्यविन्यास का उपयोग करके।पाइथन के सजावटी वाक्यविन्यास सादे रैपर सिंटैक्स की तुलना में तेज़ ज्ञापन कोड क्यों देते हैं?
मैंने फिबोनाची फ़ंक्शन को तीन अलग-अलग तरीकों से याद किया और माप लिया कि प्रत्येक ने 32 जीबी फिबोनैकी संख्या को मेरे 2.9 गीगाहर्ट्ज इंटेल कोर i7 मैकबुक प्रो पर 8 जीबी रैम और ओएस 10.9.2 के साथ दो बार पाइथन 2.7 चलाते हुए गणना की। यह मैं एक आश्चर्यजनक परिणाम दे दी है:
- नहीं Memoization बिल्कुल: 2 रों
- नियमित Memoization: 1 रों
- RWO शैली परस्पर पुनरावर्ती Memoization सादा सिंटैक्स का उपयोग: 2 रों
- RWO शैली परस्पर पुनरावर्ती Memoization का उपयोग कर डेकोरेटर वाक्य रचना: कहने के लिए
सब कुछ मैं पढ़ा है का कहना है कि डेकोरेटर वाक्य रचना वास्तव में सिर्फ वाक्यात्मक चीनी है 0.0001 रों:
memoFib = memoize(Fib)
तो # 4 से # 4 इतना तेज़ क्यों है?
from time import time
def unfib(n):
'''Unmemoized Fibonacci'''
if n <= 1: return 1
else: return unfib(n-1) + unfib(n-2)
def memoize(f):
'''A simple memoization function'''
hash = {}
def memo_f(x):
if not hash.has_key(x):
res = f(x)
hash[x] = res
return hash[x]
return memo_f
# Simple approach to memorizing Fibonacci (#2 from the list above)
memoFib1 = memoize(unfib)
# Simple approach to timing functions
def timeit(its,f,arg):
zero = time()
for i in range(its):
res = f(arg)
one = time()
print res, one - zero
# A non-recursive form of Fibonacci
# that expects the remainder of the
# function to be passed as an argument.
# Together, they make a pair of mutually
# recursive functions. Real World Ocaml
# refers to this as 'tying the recursive
# knot' (Ch. 8, Imperative programming).
def fib_norec(fib,x):
if x <= 1: return 1
else: return fib(x-1) + fib(x-2)
def memo_rec(f_norec):
'''A memoizing version of make_rec,
but using the plain wrapper
syntax of the memoize function'''
def f(x):
return f_norec(f,x)
return memoize(f)
# #3 from list above: memoized using plain call to wrapping function
memoFib2 = memo_rec(fib_norec)
def memo_rec2(f_norec):
'''A second memoizing version of
make_rec (from RWO), but using
the decorator syntax'''
@memoize
def f(x):
return f_norec(f,x)
return f
# #4 from list above, memoized using decorator syntax
memoFib3 = memo_rec2(fib_norec)
print 'no memo\t\t\t\t\t',
timeit(2,unfib,32)
print 'basic memo\t\t\t\t',
timeit(2,memoFib1,32)
print 'mutually recursive memo, plain wrapper syntax',
timeit(2,memoFib2,32)
print 'mutually recursive memo, decorator syntax',
timeit(2,memoFib3,32)