何时在Ruby on Rails中使用备忘录 [英] When to use memoization in Ruby on Rails

查看:52
本文介绍了何时在Ruby on Rails中使用备忘录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

2008年7月中旬,备忘录"已添加到Rails核心中. 此处进行了用法说明.

In mid July 2008 Memoization was added to Rails core. A demonstration of the usage is here.

关于何时应该记住方法以及每种方法对性能的影响,我还没有找到任何好的例子. 此博客文章建议经常不使用记忆.

I have not been able to find any good examples on when methods should be memoized, and the performance implications of each. This blog post, for example, suggests that oftentimes, memoization should not be used at all.

对于可能对性能产生巨大影响的东西,似乎除了提供简单的教程之外,几乎没有其他资源.

For something that could potentially have tremendous performance implications, there seem to be few resources that go beyond providing a simple tutorial.

有人在自己的项目中看到过回忆吗?哪些因素会让您考虑使用一种方法?

Has anyone seen memoization used in their own projects? What factors would make you consider memoizing a method?

在我自己进行了更多研究之后,我发现备忘录在Rails内核中被大量使用.

After doing some more research on my own I found that memoization is used a remarkable number of times inside of Rails core.

这里是一个示例: http://github .com/rails/rails/blob/1182658e767d2db4a46faed35f0b1075c5dd9a88/actionpack/lib/action_view/template.rb .

这种用法似乎与上面博客文章的发现背道而驰,因为发现备忘录会损害性能.

This usage seems to go against the findings of the blog post above that found memoization can hurt performance.

推荐答案

我认为许多Rails开发人员并不完全了解备忘录的功能以及它的工作方式.我已经看到它适用于返回延迟加载的集合的方法(如Sequel数据集),或者适用于不带参数但根据实例变量计算出结果的方法.在第一种情况下,记忆只是多余的开销;在第二种情况下,记忆是令人讨厌且难以发现错误的来源.

I think many Rails developers don't fully understand what memoization does and how it works. I've seen it applied to methods that return lazy loaded collections (like a Sequel dataset), or applied to methods that take no arguments but calculate something based on instance variables. In the first case the memoization is nothing but overhead, and in the second it's a source of nasty and hard to track down bugs.

如果

  • 返回值的计算只是有点昂贵.它必须非常昂贵,而且必须进一步优化,才能值得记忆.
  • 返回的值是或可以是延迟加载的
  • 该方法不是纯函数,即保证对于相同的参数返回完全相同的值-并且仅使用参数来完成其工作或其他纯函数.使用实例变量或调用又使用实例变量的方法意味着方法可以为相同的参数返回不同的结果.

在其他情况下,也不太适合使用记忆,例如问题中的一种和上面的答案,但是我认为这三种情况并不那么明显.

There are other situations too where memoization isn't appropriate, such as the one in the question and the answers above, but these are three that I think aren't as obvious.

最后一项可能是最重要的:记忆基于方法的参数缓存结果,如果该方法看起来像这样,则无法记忆:

The last item is probably the most important: memoization caches a result based on the arguments to the method, if the method looks like this it cannot be memoized:

def unmemoizable1(name)
  "%s was here %s" % name, Time.now.strftime('%Y-%m-%d')
end

def unmemoizable2
  find_by_shoe_size(@size)
end

但是,两者都可以重写以利用记忆(尽管在这两种情况下,显然不应出于其他原因而这样做):

Both can, however, be rewritten to take advantage of memoization (although in these two cases it should obviously not be done for other reasons):

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没有或没有任何副作用)

(assuming that find_by_shoe_size didn't have, or relied on, any side effects)

诀窍是从方法中提取纯函数,然后将备忘录应用于该函数.

The trick is to extract a pure function from the method and apply memoization to that instead.

这篇关于何时在Ruby on Rails中使用备忘录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆