I have a string-like type and would like to implement a std::format
-like function to create instances of my string-like type. A minimal working example of what I am doing is a string type with a custom allocator:
struct myalloc : std::allocator<char> {};
using mystring = std::basic_string<char, std::char_traits<char>, myalloc>;
Since std::format_to
takes an iterator, my first thought was to format to an iterator, as in:
template<class ...Args> constexpr mystring
myformat(std::format_string<Args...> fmt, Args &&...args)
{
mystring ret;
std::format_to(std::back_inserter(ret), fmt, std::forward<Args>(args)...);
return ret;
}
Unfortunately, the performance of this function is abysmal. For example, formatting a 256-byte string x256
with std::format("{}", x256)
takes around 60ns on my machine, while myformat
requires 790ns, which is 13 times slower! Those exact numbers are with gcc an an AMD EPYC CPU, but I see similar results with gcc 14.1/libstdc++ and with clang++ 18.1/libc++.
My question: how can I leverage the formatting library to create custom output types without paying such a huge performance penalty?