Нравится мне делать подобные штучки :)
Результаты бенчмарка (со всяческими другими быстрыми вариантами):
erthink ... [min 21.900ns, rms 56.925ns, max 72.200ns]
floaxie ... [min 25.200ns, rms 66.722ns, max 88.900ns]
emyg ... [min 32.600ns, rms 76.577ns, max 92.600ns]
milo ... [min 32.200ns, rms 76.754ns, max 92.400ns]
grisu2 ... [min 67.600ns, rms 89.862ns, max 110.100ns]
doubleconv ... [min 58.400ns, rms 94.065ns, max 116.500ns]
fmt ... [min 82.900ns, rms 134.049ns, max 159.000ns]
fpconv ... [min 87.400ns, rms 136.806ns, max 159.000ns]
sprintf ... [min 634.600ns, rms 717.793ns, max 783.600ns]
ostrstream ... [min 1019.400ns, rms 1104.349ns, max 1168.800ns]
ostringstream ... [min 1107.200ns, rms 1200.868ns, max 1275.700ns]
null ... [min 1.200ns, rms 1.277ns, max 1.300ns]
$ gcc -v
gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
Делюсь, думаю кому-нибудь пригодится. Лицензия zLib, исходники и бенчмарк с примером использования на github. Функция header-only и совсем не делает ничего лишнего:
- генерирует минимум символов (намеренно без десятичной точки);
- не пишет \0 в конце;
- не проверяет inf и nan (ибо во многих случаях нужна кастомная обработка, например как в json);
- но всё корректно.
Поэтому смотреть лучше начиная с примера по ссылке. При необходимости «красоты», в том числе вывода десятичной точки можно делать примерно так.