Обработчик Memoization

Это - "хорошая практика" для создания класса как тот ниже этого, может обработать процесс memoization для Вас? Преимущества memoization являются настолько большими (в некоторых случаях, как этот, где он отбрасывает с 501 003 до вызовов функции 1507 года и с 1,409 до 0,006 секунд процессорного времени на моем компьютере), что кажется, что класс как это был бы полезен.

Однако у меня есть отрицательные комментарии только для чтения по поводу использования eval(). Действительно ли это использование его простительно, учитывая гибкость этот подход предложения?

Это может сохранить любое возвращенное значение автоматически за счет проигрывающих побочных эффектов.Спасибо.

import cProfile

class Memoizer(object):
    """A handler for saving function results."""
    def __init__(self):
        self.memos = dict()
    def memo(self, string):
        if string in self.memos:
            return self.memos[string]
        else:
            self.memos[string] = eval(string)
            self.memo(string)

def factorial(n):
    assert type(n) == int
    if n == 1:
        return 1
    else:
        return n * factorial(n-1) 

# find the factorial of num
num = 500
# this many times
times = 1000

def factorialTwice():
    factorial(num)
    for x in xrange(0, times):
        factorial(num)
    return factorial(num)

def memoizedFactorial():
    handler = Memoizer()
    for x in xrange(0, times):
        handler.memo("factorial(%d)" % num)
    return handler.memo("factorial(%d)" % num)


cProfile.run('factorialTwice()')

cProfile.run('memoizedFactorial()')
10
задан 827 31 July 2010 в 07:31
поделиться

2 ответа

Вы можете мемоизировать, не прибегая к eval .

Мемоизатор (очень простой):

def memoized(f):
    cache={}
    def ret(*args):
        if args in cache:
            return cache[args]
        else:
            answer=f(*args)
            cache[args]=answer
            return answer
    return ret

@memoized
def fibonacci(n):
    if n==0 or n==1:
        return 1
    else:
        return fibonacci(n-1)+fibonacci(n-2)

print fibonacci(100)
14
ответ дан 3 December 2019 в 20:02
поделиться

eval часто неправильно пишется как зло в первую очередь потому, что идея выполнения «строк» ​​во время выполнения чревата соображениями безопасности. Достаточно ли вы ускользнули от кода? Кавычки? И множество других досадных головных болей. Ваш обработчик мемоизов работает, но на самом деле это не тот способ работы с Python. Подход MAK намного больше Pythonic. Попробуем несколько экспериментов.

Я отредактировал обе версии и заставил их запускаться только один раз со 100 на входе. Я также перенес экземпляр Memoizer . Вот результаты.

>>> timeit.timeit(memoizedFactorial,number=1000)
0.08526921272277832h
>>> timeit.timeit(foo0.mfactorial,number=1000)
0.000804901123046875

В дополнение к этому, ваша версия требует наличия оболочки вокруг функции, которая должна быть записана в виде строки. Это уродливо. Решение MAK является чистым, поскольку «процесс запоминания» заключен в отдельную функцию, которую можно удобно ненавязчиво применить к любой дорогостоящей функции. Это не очень питонично. У меня есть некоторые подробности о написании таких декораторов в моем руководстве по Python по адресу http://nibrahim.net.in/self-defence/ , если вам интересно.

5
ответ дан 3 December 2019 в 20:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: