对于一个频繁分配和释放内存的函数,哪种分配内存的方法更可取?假设此函数在1GHz处理器上每秒调用约500到1000次。
(请忽略静态和全局变量/分配。我只对这个具体案例感兴趣:)
void Test()
{
ptr=malloc(512) // 512 bytes
...
free(ptr)
}
或
void Test()
{
struct MyStruct localvar; // 512 byte sized structure
...
}
8条答案
按热度按时间vof42yt11#
局部变量的堆栈分配比
malloc
的堆分配快。然而,总堆叠空间是有限的(例如,到几兆字节)。因此,您应该将自己限制为本地堆栈上的“小”数据。(512字节按照今天的标准是小的,但是256Kb对于本地堆栈分配来说太大了)。如果你的函数是非常递归的,那么即使是512字节也可能太大了,因为每个递归调用帧都需要这个字节。
但是每秒调用几千次
malloc
应该是无痛的(恕我直言,典型的小型malloc
需要几十微秒)。出于好奇心,在C世界之外,您可能会对老A.阿 perl 的论文garbage collection can be faster than stack allocation感兴趣(但今天可能缓存性能方面的考虑会削弱这种说法)。
yruzcnhs2#
局部变量基本上是“免费”分配的,所以如果我们只对性能感兴趣,这里就没有竞争了。
不过:
tvokkenx3#
你想要更快的方式,还是更好的方式?
无论如何,在你提到的情况下,我认为第二种选择:
更有效,因为内存分配由 Stack 完成。这比使用
malloc
这样的动态内存分配函数要高效得多。优化
此外,如果您这样做是为了性能和优化…
在我的PC上,使用
malloc
来分配字符串,而不是从堆栈中声明一个char数组,这给了我每个字符串大约73纳秒的延迟。如果你在程序中复制了50个字符串:4757142 / 50 = 95142次(和一点)运行你的程序
如果我每天运行你的程序50次:95142 / 50 = 1902天(还有一点)
1902天= 5 1/5年
因此,如果你每天运行你的程序5年零2个月,你将保存额外眨眼的时间。哇,多么值得。。
4dbbbstv4#
当你输入你的函数时,打开反汇编器,并逐步完成这两种情况。
局部变量(基于堆栈)将需要0个额外的周期-您甚至看不到分配来自哪里,因为该函数将通过移动堆栈指针在1个周期内分配所有局部变量,并通过恢复堆栈指针在1个周期内释放所有局部变量。不管你有1个还是1000个局部变量,“分配”都需要相同的时间。
malloc变量...好吧,你很快就会厌倦点击步进通过成千上万的指令执行,以获得内存从系统堆。最重要的是,您可能会注意到,周期的数量因调用而异,这取决于您已经从堆中分配了多少东西,因为每次请求内存时,malloc都需要在堆结构中进行“搜索”。
我的经验法则:如果可能的话,总是使用堆栈,而不是
malloc/free
或new/delete
。除了更快的性能外,您还可以获得不必担心内存或资源泄漏的额外好处。在C中,这只是意味着忘记调用free()
,但在C++中,如果在调用delete
之前抛出异常,异常可能会毁了你的一天。如果你使用堆栈变量,这一切都是自动处理的!但是,只有当您谈论的是“小”内存(字节和KB)而不是大对象(不是MB或GB!)。如果你谈论的是巨大的对象,那么你就不再谈论性能了,而且你可能不会在同一个函数调用中调用free/delete
。btxsgosb5#
堆栈分配比
malloc
+free
快。堆栈分配通常以指令为单位来衡量,而
malloc
+free
可能需要多个锁(作为比较为什么需要很长时间的一个例子)。gk7wooem6#
局部变量的情况会更快:在堆栈上分配一个变量并不需要额外的时间,它只是改变了堆栈指针的移动量。而malloc将不得不做一些簿记。
gijlo24d7#
使用堆栈的另一个优点是它不会将内存空间分割成碎片,而malloc往往会这样做。当然,这只是长时间运行的流程的问题。
pieyvz9o8#