питон как запоминать метод - PullRequest
3 голосов
/ 16 августа 2011

Скажите, я способ создания словаря из заданных параметров:

def newDict(a,b,c,d): # in reality this method is a bit more complex, I've just shortened for the sake of simplicity
    return { "x": a,
             "y": b,
             "z": c,
             "t": d }

И у меня есть другой метод, который вызывает метод newDict каждый раз, когда он выполняется. Поэтому в конце, когда я смотрю на свой cProfiler, я вижу что-то вроде этого:

17874 calls (17868 primitive) 0.076 CPU seconds

и, конечно, мой метод newDict вызывается 1785 раз. Теперь мой вопрос: могу ли я запомнить метод newDict, чтобы сократить время вызовов? (Просто чтобы убедиться, что переменные меняются почти при каждом вызове, хотя я не уверен, влияет ли это на запоминание функции)

Под Вопрос: Я считаю, что 17k вызовов слишком много, и код не эффективен. Но, глядя на статистику, вы также можете указать, является ли это нормальным результатом, или у меня слишком много звонков, а код медленный?

Ответы [ 3 ]

9 голосов
/ 16 августа 2011
  1. Вы имеете в виду memoize, а не memorize.
  2. Если значения почти всегда различаются, запоминание не поможет, оно замедлит ход событий.
  3. Не видя вашего полного кода и не зная, что он должен делать, как мы можем узнать, много это или мало для 17k вызовов?
8 голосов
/ 16 августа 2011

Если под запоминанием вы имеете в виду запоминание, используйте functools.lru_cache.Это функция декоратора

2 голосов
/ 09 октября 2012

Цель запоминания состоит в том, чтобы сохранить результат операции, которая была дорогостоящей для выполнения, чтобы можно было предоставить второе, третье и т. Д. Время без необходимости повторения операции и многократного несения расходов.

Мемоизация обычно применяется к функции, которая (а) выполняет дорогостоящую операцию, (б) всегда дает один и тот же результат при одинаковых аргументах и ​​(в) не имеет побочных эффектов на состояние программы.

Мемоизация обычно реализуется в такой функции путем «сохранения» результата вместе со значениями аргументов, которые привели к этому результату.Это особая форма общей концепции кеша.Каждый раз, когда вызывается функция, она проверяет свой кэш заметок, чтобы увидеть, определил ли он уже результат, соответствующий текущим значениям аргументов.Если в кеше содержится результат, его можно вернуть без необходимости повторного вычисления.

Похоже, ваша функция предназначена для создания нового dict при каждом вызове.Кажется, не существует разумного способа запоминания этой функции: вы всегда хотите, чтобы вызывающий вызов возвращал новый dict, чтобы его использование полученного dict не мешало какому-либо другому вызову функции.

Единственный способ, которым я могу визуализировать, используя запоминание, было бы, если (1) вычисление одного или нескольких значений, помещенных в результат, является дорогостоящим (в этом случае я, вероятно, определил бы функцию, которая вычисляет значение изапомните эту функцию) или (2) функция newDict предназначена для возврата той же коллекции значений, заданных конкретным набором значений аргументов.В последнем случае я бы не использовал dict, а вместо этого использовал бы немодифицируемый объект (например, класс как dict, но с защитой от изменения его содержимого).

Относительно вашего подзапроса, вопросы, которые вам нужныспросить: (1) - это количество раз, когда newDict вызывается соответствующим образом, и (2) можно сократить время выполнения каждого выполнения newDict.Это два отдельных и независимых вопроса, которые должны быть индивидуально рассмотрены соответствующим образом.

Кстати, ваше определение функции содержит опечатку - в возвращении не должно быть «d» между ключевым словом return и открытой скобкой.

...