特别是记忆会在一定程度上降低性能吗?性能是否增加线性?
我有一个函数可以调用一些复杂的数学函数200,000,000次。没有memoization(保存值/缓存),它需要1米。如果我保存值 - 大约5,000,000个唯一条目 - 它仍然需要30秒。值是双倍的,我使用自己的哈希函数,哈希表大小约为20,000,000(使哈希值计算更容易)。
但复杂的数学函数仍然只运行了5,000,000次(我甚至用计数器检查过)。为什么它不能以5,000,000 / 200,000,000的大约2.5%的速度运行?
在我没有使用大型数据结构之前,现在我正在使用一个大小为20,000,000的双数组来澄清。我不知道这是否会有所作为。
答案 0 :(得分:7)
更多的内存使用量通常会显着降低性能 - 主要问题来自大型数据结构不适合您的处理器缓存并且 更长时间才能访问。
在现代处理器上,您经常会发现从头开始重做数学计算实际上要比从内存中获得结果快得多。内存访问基本上是瓶颈,而不是CPU。
此外,如果您要记忆值,那么请注意散列和查找功能的潜在开销。特别是,如果你没有正确实现你的哈希函数并且有很多哈希冲突,那么你可能会遭受非常昂贵的查询。
答案 1 :(得分:7)
所有表现问题的答案是“基准测试并找出答案”。总是。因此,您的实际运行时结果是您的答案 - 根据经验,这就是它的行为方式。您可以使用valgrind的callgrind / cachegrind工具找到 why 。
现在,我将忽略你谈论哈希的事实 - 我想你知道如果哈希计算的代价是运行函数体的成本的很大一部分,那么memoization就不会了帮助。因此,想象哈希的成本为零以下目的。
总而言之,CPU密集型代码性能的最大因素之一是缓存命中率。这是您的处理器在查找信息时是否必须通过RAM来获取它;如果它在缓存中已经很热,那么访问延迟会低几千倍,并且CPU可以更快地完成工作(我正在简化一点,因为并非所有的内存命中都会导致管道停顿,但这是它的要点)。
所以,虽然“使用更多内存”并不直接与性能下降相关(我的意思是,使用它的行为,但我假设你不是在谈论这里分配对象的成本是多少),当你有一个更宽的RAM区域,你需要的东西可能存在时,获得缓存命中的几率会降低,这会严重降低代码的运行速度。
当你的函数花费大量时间执行时,记忆只是一个胜利。通常情况就是如此,但这是一种权衡,即使在理想的情况下,将10个函数调用记忆为5也不会给你50%的理论加速。
这种违反直觉的行为(“但是Borealid,我正在做更多工作,它怎么能更快?!”)是一个很好的例子,为什么你应该经常仔细检查看看您实施的“优化”实际上提升了性能。过早优化是万恶之源。