Memory 内存效率与处理器效率

Memory 内存效率与处理器效率,memory,process,Memory,Process,在一般情况下,我应该赌内存效率还是处理器效率 最后,我知道这必须符合软件/硬件规格。但我认为没有边界是有一个普遍规律的 示例01(内存效率): int n=0; if(n

在一般情况下,我应该赌内存效率还是处理器效率

最后,我知道这必须符合软件/硬件规格。但我认为没有边界是有一个普遍规律的

示例01(内存效率):

int n=0;
if(n
示例02(处理器效率):

int n=0,aux=0;
aux=getRndNumber();
如果(n
它们只是简单的例子,写它们是为了说明我的意思。更好的例子会受到欢迎


提前感谢。

处理器效率。与处理器相比,内存速度惊人地慢。有关更多详细信息,请参阅


不过,在您的示例中,编译器可能会对这两个问题进行优化,使其等效。

我将推出通用性能问题王牌,并说“两者都不是,赌正确性”

以尽可能清晰的方式编写代码,设定具体的可测量的性能目标,测量软件的性能,对其进行分析以找出瓶颈,然后在必要时优化以了解处理器或内存是您的问题

(为了说明这一点,假设getRndNumber()不返回常量值,您的“简单示例”会有不同的行为。如果您以最简单的方式编写它,例如
n=max(0,getRndNumber())
,那么它可能效率较低,但可读性更强,更可能是正确的。)


编辑:

为了回答下面德文的批评,我可能应该说明为什么我认为这个问题没有一般性的答案

一个很好的例子是从序列中随机抽取样本。对于小到足以复制到另一个连续内存块的序列,有利于计算效率的部分Fisher-Yates洗牌是最快的方法。然而,对于内存不足的非常大的序列,必须使用有利于内存效率的库采样之类的方法;这将慢一个数量级

那么这里的一般情况是什么?对序列进行采样时,您应该考虑CPU效率还是内存效率?如果不知道序列的平均大小和最大大小、机器中的物理内存和虚拟内存量、可能采集的并发样本数、机器上运行的其他代码的CPU和内存要求等,您就无法判断,甚至像应用程序本身是否需要提高速度或可靠性这样的事情。即使你知道所有这些,你仍然只是在猜测,你不知道该支持哪一个


因此,唯一合理的做法是以有利于清晰性和可维护性的方式实现代码(考虑到您知道的因素,并假设清晰性不会以严重的低效率为代价),在实际情况中对其进行测量,以查看它是否导致了问题以及问题是什么,如果是这样,就改变它。大多数情况下,您不必更改代码,因为它不会成为瓶颈。这种方法的最终结果是,总体而言,您将拥有一个清晰且可维护的代码库,其中一些小部件尤其需要CPU和/或内存效率优化才能达到这一目的。

在过去10年中。主内存的速度几乎没有任何提高,而处理器则继续领先。没有理由相信这会改变


编辑:顺便说一句,在您的示例中,aux很可能会在寄存器中结束,并且根本不会进入内存

您希望优化的操作范围也值得考虑;如果操作是时间敏感的,比如web请求或GUI更新的一部分,那么最好是在更快地完成操作方面出错,而不是节省内存

您必须根据特定的应用程序、使用情况等做出决定。在上面的示例中,内存和处理器的使用都是微不足道的,因此这不是一个好的示例

更好的例子可能是在国际象棋搜索中使用历史表。此方法缓存先前在游戏树中搜索的位置,以防在游戏树的其他分支或下一步中重新搜索

然而,存储它们确实需要空间,而且空间也需要时间。如果您使用了太多的内存,那么最终可能会使用速度较慢的虚拟内存

另一个例子可能是数据库服务器中的缓存。显然,从主内存访问缓存的结果会更快,但再次强调,从内存中加载和释放不太可能重复使用的数据不是一个好主意


换句话说,你不能一概而论。你甚至不能根据代码做出决定——有时必须根据可能的数据和使用模式做出决定。

你认为一个与另一个无关吗?你为什么这么想?这里有两个例子,您会发现通常未经考虑的瓶颈

例1 您设计了一个与数据库相关的软件系统,发现当您读取其中一个表时,I/O正在减慢您的速度。不允许多个查询导致多个I/O操作,而是首先摄取整个表。现在表的所有行都在内存中,唯一的限制应该是CPU。拍拍自己的背,你会想,为什么你的程序在内存不足的计算机上变得异常缓慢。哦,天哪,你已经忘记了虚拟内存、交换等等

例2 您编写了一个程序,其中您的方法创建了许多小对象,但具有O(1)、O(log)或最差的O(n)速度。您已经对速度进行了优化,但请注意,您的应用程序需要很长时间才能运行。奇怪的是,你通过分析来发现罪魁祸首可能是什么。令你懊恼的是,你发现所有这些小东西加起来都很快。你的代码被GC截留了。

我想没有上下文
int n=0;   
if(n < getRndNumber())
    n = getRndNumber();
int n=0, aux=0;
aux = getRndNumber();
if(n < aux)
    n = aux;