开发者

Is it slow to do a lot of mallocs and frees on iPhone?

I have an array of point data (for particles) which constantly changes size. To adapt for the changing size, I 开发者_运维百科use code like the following to create correctly sized buffers at about 60 hz.

 free(points);
 points = malloc(sizeof(point3D) * pointCount);

Is this acceptable or is there another way I could be doing this? Could this cause my app to slow down or cause memory thrashing? When I run it under instruments in the simulator it doesn't look particular bad, but I know simulator is different from device.

EDIT: At the time of writing, one could not test on device without a developer license. I did not have a license and could not profile on device.


Allocating memory is fast relative to some things and slow relative to others. The average Objective-C program does a lot more than 60 allocations per second. For allocations of a few million bytes, malloc+free should take less than a thousand of a second. Compared to arithmetic operations, that's slow. But compared to other things, it's fast.

Whether it's fast enough in your case is a question for testing. It's certainly possible to do 60 Hz memory allocations on the iPhone — the processor runs at 600 MHz.

This certainly does seem like a good candidate for reusing the memory, though. Keep track of the size of the pool and allocate more if you need more. Not allocating memory is always faster than allocating it.


Try starting with an estimated particle count and malloc-ing an array of that size. Then, if your particle count needs to increase, use realloc to re-size the existing buffer. That way, you minimize the amount of allocate/free operations that you are doing.

If you want to make sure that you don't waste memory, you can also keep a record of the last 100 (or so) particle counts. If the max particle count out of that set is less than (let's say) 75% of your current buffer size, then resize the buffer down to fit that smaller particle count.


I'll add another answer that's more direct to the point of the original question. Most of the answers prior to this one (including my own) are very likely premature optimizations.

I have iPhone apps that do many 1000's of mallocs and frees per second, and they don't even show up in a profile of the app.

So the answer to the original question is no.


You don't need to remalloc unless the number of particles increases (or you handled a memory warning in the interim). Just keep the last malloc'd size around for comparison.


As hotpaw2 mentioned, if you need to optimise you could perhaps do so by only allocating if you need more space i.e.:

particleCount = [particles count];
if (particleCount > allocatedParticleCount) {
  if (vertices) {
    free(vertices);
  }
  if (textures) {
    free(textures);
  }
  vertices = malloc(sizeof(point3D) * 4 * particleCount);
  textures = malloc(sizeof(point2D) * 4 * particleCount);
  allocatedParticleCount = particleCount;
}

...having initialised allocatedParticleCount to 0 on instantiation of your object.

P.S. Don't forget to free your objects when your object is destroyed. Consider using an .mm file and use C++/Boost's shared_array for both vertices and textures. You would then not require the above free statements either.


In that case, you'd probably want to keep that memory around and just reassign it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜