C – How Many `malloc` Calls Are Too Many?

cmallocmemory

I'm implementing a system in C, implemented partially as a library. The library does most of the memory management itself, with the application layer just having to call *_destroy functions on the top-level objects.

While checking for memory leaks, I noticed that the number of calls to malloc seemed quite high, relative to the size of the application code. The performance of the code seems fine, but I've been bitten by "fast enough" code before when trying to scale.

The number of allocations roughly matches the number of objects created, including child objects of the top-level ones. So creating a single top-level object might trigger 7 malloc calls, since it needs one for itself and then a couple for it's children that may also need a few children.

Unfortunately, I'm relatively new to C programming, though generally experienced as a programmer, and have no idea whether or these numbers are normal or not.

So what would a good rule-of-thumb be for number of allocations? I know that less would generally be better, but changing the code to allow it would introduce complexity that I'm not willing to add without a significant increase in performance.

Also, should I worry about the performance of malloc/free or is that the realm of real-time performance (games etc.)?

Best Answer

The usual answer for this thing is to wait until you can measure if there's a problem.

My experience has been that malloc() is rarely an issue, but perhaps I also do more CPU-intensive work than you do, so malloc() isn't in the critical path.

Definitely some people are constrained by the malloc performance. See, for example, https://github.com/blog/1422-tcmalloc-and-mysql , where github switched to using TCMalloc for MySQL and got a 30% performance improvement. There's more discussion at http://www.reddit.com/r/programming/comments/18zija/github_got_30_better_performance_using_tcmalloc/ .

TCMalloc is one of several malloc replacements. Another is jemalloc, and a third is nedmalloc.

So, if you think it's a problem (eg, because profiling shows that you're stuck in malloc/free often) then try one of those out and see if it improves things.

If it's a concern now, then perhaps you can think about how your code is structured. The biggest improvement is to realize that you don't need to think of "one structure = one malloc."

For example, I once wrote a parser for a tab-separated document. While I could have turned each row and field into its own string, it was faster to scan the document, count the number of rows and columns, and do a single malloc for the row/field pointers. Then in the second step, scan the document again, assign the correct pointers to the head of each field, and replace the tabs and newlines with a NUL to get proper NUL-terminated strings for the field.

This meant that my parser now "owned" the document string, which was acceptable. And it reduced the complexity of the code, even if the malloc performance wasn't critical.

Related Topic