Ruby 数学函数记忆
我编写了一些如下所示的代码:
def get(x, y)
@cachedResults.set(x,y, Math.hypot(x, y)) if @cachedResults.get(x,y).nil?
@cachedResults.get(x,y)
end
其中 @cachedResults 包含我编写的 2D Array 类(几分钟内),该函数的目的是确保我永远不必为任何给定的 (x ,y)。 [这可以使用对称性和其他东西进一步优化,但无论如何]
所以我调用了该函数并让它运行 160000 次;它只用了 15 秒多一点就跑了。然后,为了看看它比非 Memoized 版本快了多少,我将代码更改为:
def get(x, y)
Math.hypot(x, y)
end
而且,令我惊讶的是,再次运行只花了 15 秒多一点的时间。完全相同的时间。所以我的问题是,Ruby 中的数学函数是否自然地被记忆化了?如果是这样,ruby 的记忆化程度如何?
(如果不是,那么你为什么认为我始终得到这个结果?)
I wrote some code that looks like this:
def get(x, y)
@cachedResults.set(x,y, Math.hypot(x, y)) if @cachedResults.get(x,y).nil?
@cachedResults.get(x,y)
end
Where @cachedResults contained a 2D Array class i wrote (in a few minutes) and the purpose of this function is to make sure that I never have to call Math.hypot twice for any given (x,y). [This could be optimised further using symmetry and other things but whatever]
So I called the function and let it run 160000 times; it ran in just over 15 seconds. Then, to see how much faster it was than the non Memoized version, i changed the code to this:
def get(x, y)
Math.hypot(x, y)
end
And, much to my surprise, it took just over 15 seconds to run again. The exact same time. So my question is, are the maths functions in ruby naturally Memoized? And, if so, to what extent is ruby Memoized?
(If not then why do you think I am getting this result consistently?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你是否需要大约 15 秒才能完成某件事 160000 次?在您的系统上对其进行基准测试,仅返回 x;与解释器开销相比,hypot 操作(用 C 实现)很可能可以忽略不计。
对于使用 khell 的 memoized get 方法的 ruby 1.8.7,在 get 方法内调用该函数,并仅在 get 方法内返回 x,迭代 100000 次:
kheill 的 memoization 在每次调用时都会创建一个字符串,这比调用 C 的成本要高得多每次调用时都会使用库的hypot 函数。
调用hypot 和仅返回x 之间的差异表明hypot 仅贡献了25% 的运行时间。这不是您应该优化的代码 - 相反,如果可以的话,请尝试内联对库的调用,而不是将其包装在另一个方法中。
这
不是
foo 是一个带有发布方法的对象。
这些时间是在上网本(Asus eeepc 900)上进行的,上网本的速度不是很快,所以它们比您的时间快得多,这有点奇怪。因此,其他因素可能会主导您的结果。
Does it take around 15 seconds to do anything 160000 times for you? Benchmark it on your system just returning x; it may well be that the hypot operation ( implemented in C ) is negligible than the interpreter overhead.
For ruby 1.8.7 with khell's memoized get method, calling the function inside a get method, and just returning x inside a get method, with 100000 iterations:
kheill's memoization creates a string on every call, which is much more costly than calling the C library's hypot function on every call.
The difference between the calling hypot and just returning x indicates that hypot is only contributing 25% of the runtime. It's not the code you should be optimising - instead try inlining the call to the library if you can rather than wrapping it in another method.
which is
rather than
where foo is an object with the methods posted.
These times were on a netbook ( Asus eeepc 900 ) which isn't massively speedy, so it's a bit odd that they are much faster than your times. So something else might be dominating your results.
试试这个:
Try this:
在这种情况下,我不期望这里的记忆会有很大提高。
Math.hypot 所做的只是
sqrt(x**2 + y**2)
。它不是对已计算值的递归调用。I won't expect a memorization here will improve a lot in this case.
What Math.hypot do is just
sqrt(x**2 + y**2)
. It is not an recursive call to already caculated value.