我知道这是一个古老的问题,但是有些事情似乎每个人都缺失。
首先,这是乘以2:尺寸<< 1。这是乘以任何1和2之间:INT(浮动(大小)* x),其中x是数量,*是浮点数学和处理器具有运行有关在float和int之间进行转换的附加说明。换句话说,在机器级别,加倍需要一条非常快速的指令来找到新的大小。乘以1到2之间的值至少需要一条指令将大小转换为浮点数,另一条指令进行乘法运算(这是浮点乘法,因此它可能至少需要两倍的周期,如果不是四倍甚至八倍的话),而另一条指令则转换为int,并且假定您的平台可以在通用寄存器上执行浮点数学运算,而不需要使用特殊寄存器。简而言之,您应该期望每个分配的数学运算至少要花费简单左移时间的10倍。但是,如果您在重新分配期间要复制大量数据,则可能没有太大区别。
其次,可能还有一个大的推动力:每个人似乎都认为正在释放的内存既与自身相邻,又与新分配的内存相邻。除非您自己预先分配所有内存,然后将其用作池,否则几乎肯定不是这种情况。操作系统可能偶尔最终这样做,但是在大多数情况下,将会有足够的可用空间碎片,以至于任何一半的像样的内存管理系统都将能够找到一个适合您的内存的小孔。一旦真正掌握了块,就更有可能产生连续的块,但是到那时,您的分配就足够大了,以至于您没有足够频繁地进行分配,就不再重要了。简而言之,有趣的是,使用一些理想的数字可以最有效地利用可用内存空间,但是实际上,除非您的程序在裸机上运行(例如,没有操作系统),否则这不会发生在它下面做出所有决定)。
我对这个问题的回答?不,没有理想的数字。它是如此特定于应用程序,因此没有人真正尝试过。如果您的目标是理想的内存使用率,那么您很不走运。为了提高性能,分配频率越低越好,但是如果我们这样做,则可以乘以4甚至8!当然,当Firefox一次使用1GB的存储空间跃升至8GB的存储空间时,人们会抱怨,所以这甚至毫无意义。这是我会遵循的一些经验法则:
如果您无法优化内存使用率,至少不要浪费处理器周期。乘以2至少比进行浮点数学运算快一个数量级。它可能不会产生太大的变化,但是至少会有所不同(尤其是在较早的阶段,在更频繁和更小的分配期间)。
不要想太多。如果您只花了4个小时来弄清楚如何做已经完成的事情,那您就浪费了时间。坦白地说,如果有比* 2更好的选择,那将在几十年前的C ++向量类(以及许多其他地方)中完成。
最后,如果您真的想优化,请不要流血。如今,除非有人在嵌入式系统上工作,否则没人会在意4KB的内存浪费。当获得1GB的对象(每个对象介于1MB和10MB之间)时,加倍可能太多了(我的意思是,这在100到1,000个对象之间)。如果您可以估计预期的扩展速度,则可以在特定点将其扩展为线性增长率。如果您希望每分钟大约有10个对象,那么以每步5到10个对象大小(每30秒到一分钟一次)的速度增长可能很好。
最终的结果就是,不要过度思考,优化您可以做的,并在必要时针对应用程序(和平台)进行自定义。