在一般情况下,我应该押注于内存效率还是处理器效率?
最后,我知道这必须根据软件/硬件规范。但我认为,当没有边界时,有一个普遍的规则。
示例01 (内存效率):
int n=0;
if(n < getRndNumber())
n = getRndNumber();示例02 (处理器效率):
int n=0, aux=0;
aux = getRndNumber();
if(n < aux)
n = aux;它们只是一些简单的示例,为了说明我的意思而编写它们。更好的例子将受到好评。
提前谢谢。
发布于 2009-12-30 08:45:54
我将推出通用的性能问题王牌,并说“都不是,赌正确性”。
以尽可能清晰的方式编写代码,设置具体的可测量的性能目标,测量软件的性能,分析它以找到瓶颈,然后在必要时优化了解是处理器还是内存是您的问题。
(似乎是为了举例说明,假设getRndNumber()不返回常量值,您的“简单示例”具有不同的行为。如果您以最简单的方式编写它,比如n = max(0, getRndNumber()),那么它可能效率较低,但可读性更好,更有可能是正确的。)
编辑:
为了回答下面Dervin的批评,我可能应该说明为什么我认为这个问题没有通用的答案。
一个很好的例子是从序列中随机抽取样本。对于足够小的序列,可以复制到另一个连续的内存块中,部分Fisher-Yates混洗是最快的方法,它有利于提高计算效率。但是,对于内存不足的非常大的序列,必须使用诸如储存器采样之类的方法来提高内存效率;这将会慢一个数量级。
那么这里的一般情况是什么呢?对于序列采样,您应该考虑CPU效率还是内存效率?如果不知道序列的平均大小和最大大小、机器中的物理和虚拟内存量、可能的并发采样数量、机器上运行的其他代码的CPU和内存需求,甚至应用程序本身是否需要速度或可靠性之类的东西,您根本无法判断。即使你知道所有这些,那么你仍然只是猜测,你并不真的知道偏爱哪一个。
因此,唯一合理的做法是以一种有利于清晰度和可维护性的方式实现代码(考虑到您知道的因素,并假设清晰度不会以牺牲严重的低效为代价),在现实生活中测量它,看看它是否造成了问题以及问题是什么,如果是,则对其进行修改。大多数情况下,您不必更改代码,因为它不会成为瓶颈。这种方法的最终结果是,总体上你将拥有一个清晰和可维护的代码库,特别需要CPU和/或内存效率的小部分也会进行优化。
发布于 2009-12-31 07:45:53
你认为其中一个与另一个无关?你为什么那么想?这里有两个例子,你会发现经常没有考虑到的瓶颈。
示例1
您设计了一个与数据库相关的软件系统,当您读取其中一个表时,发现I/O正在减慢您的速度。您不允许多个查询导致多个I/O操作,而是首先摄取整个表。现在表中的所有行都在内存中,唯一的限制应该是CPU。夸耀自己,你想知道为什么你的程序在内存不足的计算机上变得可怕地慢。哦,天哪,你已经忘记了虚拟内存、交换等等。
示例2
你写了一个程序,你的方法创建了许多小对象,但拥有O(1),O(log)或最差的O(n)速度。您已经针对速度进行了优化,但是发现您的应用程序需要很长时间才能运行。令人好奇的是,你通过分析来发现罪魁祸首是什么。让你恼火的是,你发现所有这些小东西加起来都很快。你的代码被GC阻止了。
发布于 2009-12-30 10:14:46
你必须根据特定的应用程序,使用情况等来决定。在上面的例子中,内存和处理器的使用都是微不足道的,所以不是一个好的例子。
一个更好的例子可能是在国际象棋搜索中使用历史表。此方法将先前搜索的位置高速缓存在游戏树中,以防在游戏树的其他分支中或在下一次移动时重新搜索它们。
然而,存储它们确实需要空间,而且空间也需要时间。如果你使用了太多的内存,你可能最终会使用虚拟内存,这将会很慢。
另一个例子可能是数据库服务器中的缓存。显然,从主内存访问缓存的结果会更快,但是,继续加载和释放不太可能重用的内存数据也不是一个好主意。
换句话说,你不能一概而论。您甚至不能基于代码做出决定-有时必须在可能的数据和使用模式的上下文中做出决定。
https://stackoverflow.com/questions/1977829
复制相似问题