3

让我们以这个示例场景为例:

存在一个非常复杂的函数,它涉及数学平方根和立方根(处理速度较慢)来计算其输出。例如,让我们假设函数接受两个参数ab并且值 a 和 b 的输入范围都是明确定义的。让我们假设输入值ab的范围是 0 到 100。

因此,本质上fn(a,b)可以实时计算,也可以将其结果预填充到数据库中,并在需要时获取。

方法一:实时计算

function fn(a,b){

result = compute_using_cuberoots(a,b)

return result
}

方法二:从数据库中获取函数结果

我们有一个预先填充了映射到相应结果的输入值的数据库:

a   |  b  | result
0   |  0  |   12.4
1   |  0  |   14.8
2   |  0  |   18.6
.   |  .  |    .
.   |  .  |    .
100 | 100 |  1230.1

我们可以

function fn(a,b){

result = fetch_from_db(a,b)

return result
}

我的问题:

你会提倡哪种方法,为什么?为什么你认为一种方法比另一种更有效?

我相信这是我们大多数人在编程生活中的某个时候会面临的一个场景,因此也是这个问题。

谢谢你。

问题背景(可能不相关)

示例:在像图像处理这样的场景中,可能会更频繁地遇到这种情况,其中输入 (R,G,B) 的值范围是已知的 (0-255) 并且平方根的数学计算和立方体根为完成服务器请求引入了太多时间。

让我们举个例子,你正在构建一个像 Instagram 这样的应用程序 - 处理用户发送到服务器的图像所花费的时间和返回处理后的图像所花费的时间必须保持最小,以获得最佳的用户体验。在这种情况下,重要的是尽量减少处理图像所花费的时间。更糟糕的是,当此类处理请求的数量变得很大时,就会引入可伸缩性问题。

因此,有必要在上述方法之一之间进行选择,这也是在这种情况下的最佳方法。

有关我的情况的更多详细信息(如果需要):

框架: Ruby on Rails,数据库: MongodB

4

5 回答 5

3

我不会提倡任何一种方法,我会测试它们(如果我认为它们都是合理的)并获取一些数据。

写完之后,我要上钩了:考虑到计算与 I/OI 的相对速度,预计计算比从数据库中检索函数值要快。我会承认在某些特殊情况下内存数据库将能够胜过(重新)计算的可能性(仅此而已),但作为一般规则,不会。

于 2012-03-02T11:00:43.307 回答
2

如果输入是固定值,则计算结果和从表中读取可能是一个很好的解决方案。如果输入在不同情况下发生变化,则计算实时和缓存结果以获得最佳时间可能是一个很好的解决方案。

“我们应该忘记小的效率,比如大约 97% 的时间:过早的优化是万恶之源” Donald Knuth

于 2012-03-02T11:22:38.370 回答
2

“更有效”是一个模糊的术语。“更快”更具体。

如果您谈论的是 SQL 数据库表中的几百万行,那么选择单行可能比计算结果要快。在商用硬件上,使用未经调整的服务器,我通常可以在十分之几毫秒内从数百万行的索引表中返回单行。但在安装 dbms 服务器并仅为此目的构建数据库之前,我会仔细考虑。

为了使“更快”不那么具体,当您谈论用户体验时,在一定范围内,实际速度不如表观速度重要。在正确的时间提供正确的反馈会让人们觉得事情进展得很快,或者至少让他们觉得等待一点点没什么大不了的。有关如何执行此操作的详细信息,我将查看Stack Exchange 网络上的用户体验。

好消息是测试两种方式都非常简单。对于这个特定问题的速度测试,您甚至不需要在数据库中存储正确的值。您只需要拥有正确的键和索引。如果计算正确的值需要一整天,我会考虑这样做。

您可能应该在很长一段时间内进行测试。我希望 dbms 的速度会有更多变化。不过,我不知道你应该期待多少变化。

于 2012-03-02T11:57:25.713 回答
0

我会考虑使用哈希作为计算和存储的组合。他非常复杂的函数表示为a**b

lazy = Hash.new{|h,(a,b)|h[[a,b]] = a**b}
lazy[[4,4]]
p lazy #=> {[4, 4]=>256}
于 2012-03-02T13:16:17.297 回答
0

我会考虑将值存储在代码本身上:

class MyCalc
  RESULTS = [
    [12.4, 14.8, 18.6, ...]
    ...
    [..., 1230.1]
  ]
  def self.fn a, b
    RESULTS[a][b]
  end
end

MyCalc.fn(0,1)         #=> 14.8
于 2012-03-02T13:37:51.493 回答