Python func_dict привыкший к memoize; другие полезные приемы?

Я использую KDiff3 в качестве инструмента слияния с 3 путями. Это делает достойное задание.

6
задан behindthefall 19 November 2009 в 03:02
поделиться

2 ответа

Просто будьте осторожны: fib. Трюк с cache работает только в том случае, если fib действительно является именем соответствующего объекта функции в области, которая активна во время ее выполнения (например, когда вы украшаете его, как вы это сделали, вы должны назначить начальный значение для кэша в оболочку декоратора, а не в декорированную функцию - и если после этого он будет дополнительно украшен, все сломается).

Это немного хрупко по сравнению со стандартной идиомой мемоизации:

def fib(n, _memo={0:1, 1:1}):
    if n in _memo:
        return _memo[n]
    else:
        _memo[n] = fib(n-1) + fib(n-2)
        return _memo[n]

или декоратором эквивалент.Стандартная идиома также быстрее (хотя и ненамного) - поместив их обе в mem.py под именами fib1 (.cache-trick, без отпечатков и без украшений) и fib2 (моя версия), мы видим ...:

$ python -mtimeit -s'import mem' 'mem.fib1(20)'
1000000 loops, best of 3: 0.754 usec per loop
$ python -mtimeit -s'import mem' 'mem.fib2(20)'
1000000 loops, best of 3: 0.507 usec per loop

, поэтому версия со стандартной идиомой экономит около 33% времени, но это когда почти все вызовы действительно попадают в кеш мемоизации (который заполняется после первого из этого миллиона циклов) - преимущество в скорости fib2 меньше в кеше отсутствует, поскольку это происходит из-за более высокой скорости доступа к _memo (локальная переменная) по сравнению с fib.cache (глобальное имя, fib, а затем его атрибут, кеш), и обращения к кешу преобладают при попадании в кеш (больше ничего нет ;-), но есть небольшая дополнительная работа (равная для обеих функций) при промахах кеша.

В любом случае, не собирайтесь опускать руки на ваш парад,но когда вы найдете какую-нибудь новую крутую идею, обязательно сравните ее со «старым добрым способом», как с точки зрения «надежности», так и с точки зрения производительности (если вы кэшируете, вероятно, вы заботитесь о производительность; -).

7
ответ дан 16 December 2019 в 21:41
поделиться

Я всегда использовал эту технику для запоминания. В ней используется тот факт, что можно вызвать объект, который не является функцией, при условии, что для этого объекта определен метод __call__. По какой бы то ни было причине мне не пришло в голову ни метод, ни Алекс Мартелли. Я бы догадался, что производительность примерно такая же, как у закулисного метода, потому что он работает примерно так же. Может быть немного медленнее. Но, как указывает страница со ссылкой, "определение для fib() теперь является "очевидным", без кэширования кода, загораживающего алгоритм", что вроде как мило.

1
ответ дан 16 December 2019 в 21:41
поделиться
Другие вопросы по тегам:

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