哪种方式为经常分配和释放内存的函数分配内存?假设此功能在1GHz处理器上每秒被调用大约500到1000次。
(请忽略静态和全局变量/分配。我只对这个特定情况感兴趣:)
void Test()
{
ptr=malloc(512) // 512 bytes
...
free(ptr)
}
OR
void Test()
{
struct MyStruct localvar; // 512 byte sized structure
...
}
答案 0 :(得分:20)
局部变量的堆栈分配比malloc
的堆分配快。但是,总堆栈空间是有限的(例如,几兆字节)。因此,您应该将自己限制为本地堆栈上的“小”数据。 (根据今天的标准,512字节很小,但256Kb对于本地堆栈分配来说太大了。)
如果你的函数是非常递归的,那么甚至512字节也可能太大,因为你需要为每个递归调用框架。
但是每秒呼叫malloc
几千次应该是无痛的(恕我直言,典型的小型malloc
需要几十微秒)。
为了您的好奇心,在C世界之外,您可能会对旧A.Appel的论文garbage collection can be faster than stack allocation感兴趣(但可能缓存性能考虑因素可能会削弱今天的声明)。
答案 1 :(得分:6)
本地变量基本上是“免费”分配的,所以如果我们只对性能感兴趣,那么就没有竞争。
然而:
答案 2 :(得分:3)
- 分配内存的方式....
- 哪个分配更快?
您想要更快的方式,还是更好的方式?
无论如何,在你提到的情况下,我认为第二个选择:
struct MyStruct localvar;
更有效,因为内存分配是由 Stack 完成的。使用动态内存分配函数(如malloc
。
另外,如果你这样做是为了表现&优化...
在我的电脑上,使用malloc
分配字符串而不是从堆栈中声明一个char数组,每个字符串的延迟为~73纳秒。
如果您在程序中复制了50个字符串: 4757142/50 = 95142(并且有点)运行您的程序
如果我每天运行您的程序50次: 95142/50 = 1902(有点)天
1902天= 5年1/5年
因此,如果您每天运行您的程序5年零2个月,您将节省时间眨眼睛额外的时间。哇,多么有意义......
答案 3 :(得分:2)
进入功能时打开反汇编程序,然后逐步完成2个案例。
局部变量(基于堆栈)将需要0个额外的周期 - 你甚至不会看到分配的来源,因为该函数将通过移动堆栈指针在1个周期内分配所有局部变量,并释放所有通过恢复堆栈指针在1个周期中的局部变量。如果你有1或1000个局部变量并不重要,“分配”需要相同的时间。
malloc变量......好吧,您将很快无聊点击执行数千条执行指令以从系统堆中获取内存。最重要的是,您可能会注意到循环次数因呼叫而异,具体取决于您已经从堆中分配了多少内容,因为每次请求内存时malloc都需要通过堆结构“搜索”。
我的经验法则:如果可能,请始终使用堆栈,而不是malloc/free
或new/delete
。除了更快的性能之外,您还可以获得额外的好处,而不必担心内存或资源泄漏。在C中,这只是意味着忘记调用free()
,但是在C ++中,如果在调用delete
之前抛出异常,则异常会毁掉你的一天。如果使用堆栈变量,则全部自动处理!但是,如果您正在谈论“小”内存(字节和KB)而不是大型对象(不是MB或GB!),则只使用堆栈。如果你正在谈论巨大的物体,你不再谈论性能,你可能不会在同一个函数调用中调用free/delete
。
答案 4 :(得分:1)
堆叠分配比malloc
+ free
快。
堆栈分配通常在指令中测量,而malloc
+ free
可能需要多次锁定(作为比较需要很长时间的原因的一个示例)。
答案 5 :(得分:1)
局部变量的情况要快得多:在堆栈上分配变量不需要额外的时间,它只是改变堆栈指针的移动量。而malloc将不得不做一些簿记。
答案 6 :(得分:1)
使用堆栈的另一个好处是它不会分割内存空间,malloc倾向于这样做。当然,这只是长期运行流程的一个问题。