简体   繁体   English

哪个分配更快? malloc vs局部变量

[英]Which allocation is faster ? malloc vs local variable

Which is preferable way to allocate memory for a function that is frequently allocating and freeing memory ? 哪种是为频繁分配和释放内存的函数分配内存的首选方法? Assume this function is getting called around 500 to 1000 times a second on a 1GHz Processor. 假设此功能在1GHz处理器上每秒调用大约500到1000次。

(Please ignore static and global variables/allocation. I am interested only this specific case:) (请忽略静态和全局变量/分配。我只对这个特定情况感兴趣:)

void Test()
{
    ptr=malloc(512)   // 512 bytes
    ...
    free(ptr) 
}

OR 要么

void Test()
{
     struct MyStruct localvar; // 512 byte sized structure
     ... 
}

stack allocation of local variables is faster than heap allocation with malloc . 局部变量的堆栈分配比使用malloc堆分配更快。 However, the total stack space is limited (eg to several megabytes). 但是,总堆栈空间有限(例如,几兆字节)。 So you should limit yourself to "small" data on the local stack. 因此,您应该将自己限制为本地堆栈上的“小”数据。 (and 512 bytes is small by today's standard, but 256Kb would be too large for local stack allocation). (根据今天的标准,512字节很小,但256Kb对于本地堆栈分配来说太大了)。

If your function is very deeply recursive, then perhaps even 512 bytes could be too big, because you'll need that for each recursive call frame. 如果你的函数是非常递归的,那么甚至512字节也可能太大,因为你需要为每个递归调用帧。

But calling malloc a few thousands time per second should be painless (IMHO a typical small-sized malloc takes a few dozens of microseconds). 但是每秒钟调用malloc几千次应该是无痛的(恕我直言,典型的小型malloc需要几十微秒)。

For your curiosity, and outside of the C world, you might be interested by old A.Appel's paper garbage collection can be faster than stack allocation (but perhaps cache performance considerations could weaken this claim today). 为了您的好奇心,在C世界之外,您可能对旧的感兴趣A.Appel的纸质垃圾收集可能比堆栈分配更快 (但可能缓存性能考虑因素可能会削弱今天的声明)。

Local variables are allocated essentially "for free", so there is no contest here if we are only interested in performance. 本地变量基本上是“免费”分配的,所以如果我们只对性能感兴趣,那么这里没有竞争。

However: 然而:

  • the choice between a local and a heap-allocated variable is not normally something that you are free to decide without constraint; 在本地和堆分配的变量之间的选择通常不是你可以自由决定的,没有约束; usually there are factors that mandate the choice, so your question is a bit suspect because it seems to disregard this issue 通常有一些因素要求选择,所以你的问题有点怀疑,因为它似乎无视这个问题
  • while allocating on the stack is "free" performance-wise, space on the stack might be limited (although of course 512 bytes is nothing) 虽然在堆栈上分配是“免费的”性能,但堆栈上的空间可能是有限的(尽管当然512字节是没有的)
  • Which is preferable way to allocate memory.... 这是分配内存的最佳方式....
  • Which allocation is faster ? 哪个分配更快

Do you want the faster way,or the preferable way? 你想要更快的方式,还是更好的方式?

Anyway, in the case you mentioned, I think the second option: 无论如何,在你提到的情况下,我认为第二种选择:

struct MyStruct localvar;

is more efficient, since the memory allocation is done by the Stack . 更高效,因为内存分配是由堆栈完成的。 Which is a lot more efficient that using dynamic memory allocation functions like malloc . 使用像malloc这样的动态内存分配函数,效率要高得多。

Optimizing 优化

Also, if you are doing this for performance & optimizing... 此外,如果你这样做是为了表现和优化......

On my PC, using malloc to allocate strings instead of declaring a char array from the stack gives me a lag of ~ 73 nanoseconds per string. 在我的电脑上,使用malloc来分配字符串而不是从堆栈中声明一个char数组给我一个每串约73纳秒的延迟。

if you copied 50 strings in your program: 4757142 / 50 = 95142 (and a bit) runs of your program 如果你在程序中复制了50个字符串:4757142/50 = 95142(并且有点)运行你的程序

If I run your program 50 times a day: 95142 / 50 = 1902 (and a bit) days 如果我每天运行你的程序50次:95142/50 = 1902(和一点点)天

1902 days = 5 1/5 years 1902天= 5 1/5年

So if you run your program every day for 5 years and 2 months, you'll save the time to blink your eye an extra time. 因此,如果您每天运行您的程序5年零2个月,您将节省时间眨眼睛额外的时间。 Wow, how rewarding... 哇,多么有意义......

Turn on your disassembler when you enter your function, and step through the 2 cases. 输入功能时打开反汇编程序,然后逐步完成2个案例。

The local variable (stack based) will require 0 extra cycles -- you won't even see where the allocation comes, because the function will allocate all the local variables in 1 cycle by just moving the stack pointer, and free all the local variables in 1 cycle by restoring the stack pointer. 局部变量(基于堆栈)将需要0个额外的周期 - 你甚至不会看到分配的来源,因为函数将通过移动堆栈指针在1个周期内分配所有局部变量,并释放所有局部变量通过恢复堆栈指针在1个周期内完成。 It doesn't matter if you have 1 or 1000 local variables, the "allocation" takes the same amount of time. 如果你有1或1000个局部变量并不重要,“分配”需要相同的时间。

The malloc variable ... well, you will quickly get bored click-stepping through the thousands of instructions that are executed to get memory from the system heap. malloc变量......好吧,你会很快无聊地点击执行数千条指令来执行以从系统堆中获取内存。 On top of that, you might notice that the number of cycles varies from call to call, depending on how many things you have already allocated from the heap, as malloc requires a "search" through the heap structure every time you ask for memory. 最重要的是,您可能会注意到循环次数因呼叫而异,具体取决于您已经从堆中分配了多少内容,因为每次请求内存时malloc都需要通过堆结构“搜索”。

My rule of thumb : always use the stack if possible, instead of malloc/free or new/delete . 我的经验法则 :如果可能的话,总是使用堆栈,而不是malloc/freenew/delete In addition to faster performance, you get the added benefit of not having to worry about memory or resource leaks. 除了更快的性能之外,您还可以获得额外的好处,而不必担心内存或资源泄漏。 In C this just means forgetting to call free() , but in C++ exceptions can ruin your day if something throws an exception before you call delete . 在C中,这只是意味着忘记调用free() ,但是在C ++中,如果调用delete 之前抛出异常异常会毁掉你的一天。 If you use stack variables, this is all handled automatically! 如果使用堆栈变量,则全部自动处理! However, only use the stack if you are talking about "small" pieces of memory (bytes and KB) and not huge objects (not MB or GB!). 但是,如果您正在谈论“小”内存(字节和KB)而不是大型对象(不是MB或GB!),则只使用堆栈。 If you are talking about huge objects anyways, you are not talking about performance any more and you will probably not be calling free/delete in the same function call anyways. 如果你正在讨论巨大的物体,你不再谈论性能,你可能不会在相同的函数调用中调用free/delete

Stack allocation is faster than malloc + free . 堆栈分配比malloc + free更快。

Stack allocations are typically measured in instructions, while malloc + free may require multiple locks (as one example of why it takes long in comparison). 堆栈分配通常在指令中测量,而malloc + free可能需要多个锁(作为比较需要很长时间的原因的一个示例)。

The local variable case will be much faster: allocating a variable on the stack takes no extra time, it just changes the amount the stack pointer is moved. 局部变量的情况要快得多:在堆栈上分配变量不需要额外的时间,它只是改变堆栈指针的移动量。 Whereas malloc will have to do some bookkeeping. 而malloc将不得不做一些簿记。

Another advantage by using the stack is that it does not fragment the memory space, which the malloc has a tendency to do. 使用堆栈的另一个好处是它不会分割内存空间,malloc倾向于这样做。 Of course this is just an issue for long-running processes. 当然,这只是长期运行流程的一个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM