Я думаю, что многие разработчики Rails не до конца понимают, что делает мемоизация и как она работает. Я видел, что он применяется к методам, которые возвращают лениво загруженные коллекции (например, набор данных Sequel), или применяется к методам, которые не принимают аргументов, но вычисляют что-то на основе переменных экземпляра. В первом случае запоминание - не что иное, как накладные расходы, а во втором - источник неприятных и трудно выявляемых ошибок.
Я бы не применил бы памятку, если
- возвращаемое значение просто немного дороже для вычисления. Он должен быть очень дорогим и не подлежать дальнейшей оптимизации, чтобы его стоило запомнить.
- возвращаемое значение загружено или может быть отложено
- метод не является чистой функцией, т. Е. Он гарантированно возвращает одно и то же значение для тех же аргументов - и использует только аргументы для своей работы или другие чистые функции. Использование переменных экземпляра или вызова методов, которые в свою очередь используют переменные экземпляра, означает, что метод может возвращать разные результаты для одинаковых аргументов.
Есть и другие ситуации, когда запоминание не подходит, например, вопрос в вопросе и ответы выше, но я думаю, что эти три не столь очевидны.
Последний элемент, вероятно, является наиболее важным: запоминание кэширует результат на основе аргументов метода, если метод выглядит так, его нельзя запомнить:
def unmemoizable1(name)
"%s was here %s" % name, Time.now.strftime('%Y-%m-%d')
end
def unmemoizable2
find_by_shoe_size(@size)
end
Оба могут, однако, быть переписаны, чтобы использовать в своих интересах запоминание (хотя в этих двух случаях это явно не должно быть сделано по другим причинам):
def unmemoizable1(name)
memoizable1(name, Time.now.strftime('%Y-%m-%d'))
end
def memoizable1(name, time)
"#{name} was here #{time}"
end
memoize :memoizable1
def unmemoizable2
memoizable2(@size)
end
def memoizable2(size)
find_by_shoe_size(size)
end
memoize :memoizable2
(при условии, что find_by_shoe_size
не имеет или полагается на какие-либо побочные эффекты)
Хитрость заключается в том, чтобы извлечь из метода чистую функцию и применить к ней памятку.