W
websnarf
There's a simple rule for optimisation: Don't optimise unless you have
measured it and found that optimising is needed.
Indeed, but that's just a corollary for what H.L. Mencken said: "For
every complex problem, there is an answer that is clear, simple--and
wrong." And you definitely got that last part as I will explain:
[...] In my test, I did one
billion realloc's, with the size growing from one byte to one billion
byte, and the time was 55 ns per realloc (time printed every 1 million
iterations, so it could easily be that a few reallocs took
significantly longer), with no apparent growth as the block size got
bigger.
Not surprising; most memory allocator strategies will behave well in
view of trivial scenarios. But if you do a *sequence* of mallocs and
then try to resize them at random, then tell me what kind of
performance you get.
Anyway, if _you_ can find a clever strategy to choose sizes for
allocations, why shouldn't the author of the library?
The library author doesn't know which trade off the application
developer has in mind. If the system library favors performance then
it *cannot* favor memory tightness, and does not allow the application
developer to work around the system's implementation. On the other
hand if the system library provider provides a memory efficient
implementation, then either of Jef Driesen's first two strategies
works very well no matter what kind of realloc implementation has been
provided. In other words, the app developer can deal with performance
on his own.
[...] He's in a much better position.
How can a position of ignorance be a better position? The system
library provider can never know which trade off the application
developer wants.
[...] For example, he can allocate more memory than needed
for a malloc block to make realloc faster, but cut away from that
block when needed.
That is rarely relevant. You just have to implement a next block
pointer and see if the adjacent block is unallocated and contains
enough space to be extended into. That's not the issue. The issue is
how often the next block is really going to be allocated or not. With
tight allocation strategies, which are the norm, you can never know.
If you preallocate too much space, then you will just run out of space
faster (as if you had less ram in your system than you actually paid
for and installed). That's not something that can ever be worked
around, and I would never want to use a system that implemented such a
trade off.
Even as an app developer, if you want to use a strategy where you are
willing to eat excess memory to improve allocation performance, you
are going to want to use a pool based system, which is a totally
different strategy (that is very bad for re-use but good for
allocation speed) and needs to be custom developed by the app
developer anyways.