So deep inside a library I need a function which allocates a string, writes a provided floating point number to the string with %f format, and returns it. snprintf() returns the number of characters that would be needed, which would allow me to allocate the right size with 2 snprintf() calls. Unfortunately this is a somewhat performance-critical piece, so I’d like to avoid that as *printf() can be slow (yes, in some benchmarks it does show up at #1 on the profile).
Another way is to use some of the C99 functions to figure it out, but libm calls take a fair bit of time as well. A (very much simplified, no error handling etc.) version of my function would look something like the following
// Return a string containing number x in %f format with d digits after the decimal point.
char* my_function(double x, int d)
{
int n = ceil(log10(pow(2, ilogb(x))));
// 3 extra chars, the initial sign, the ".", and the terminating null.
char *s = malloc(n + d + 3);
snprintf(s, n + d+ 3, "%#-+.*f", d, x);
return s;
}
A potentially even faster way would be to allocate a string which is "large enough", and then do the second snprintf call only if the unlikely happened and it turned out to be too short.
It's also possible to structure the code so that I can use stack allocation with alloca() and/or C99 VLA's, but as stack space is often quite limited I'd like to avoid blowing a lot of memory on a worst-case sized buffer.
Any better idea?
Are you running in a memory constrained system? If you’re not at the point where you really need to count bytes, simply determine your worst case and make all allocations this size.
Another option is to make the caller provide the buffer.
Finally, do you know if you can state that there will not be a need for more than a finite number of these values to exist at once? If so, pre-allocate the space for them and don’t do the malloc() within your function. Since you say performance is critical, you should be trying to avoid malloc() as well.