Block optimize pragma on EDG (#4980) EDG over GCC likes to pretend to be GCC in a lot of macros, but not all. It does not define `__OPTIMIZE__` ever. So we would erroneously emit pragma optimize `Og` even in optimized builds.
{fmt} is an open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams.
Q&A: ask questions on StackOverflow with the tag fmt.
Try {fmt} in Compiler Explorer.
(s)printf, iostreams, to_string and to_chars, see Speed tests and Converting a hundred million integers to strings per secondcore.h, format.h and format-inl.h, and compiled code; see Compile time and code bloat-Wall -Wextra -pedanticFMT_HEADER_ONLY macroSee the documentation for more details.
Print to stdout (run)
#include <fmt/core.h> int main() { fmt::print("Hello, world!\n"); }
Format a string (run)
std::string s = fmt::format("The answer is {}.", 42); // s == "The answer is 42."
Format a string using positional arguments (run)
std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy"); // s == "I'd rather be happy than right."
Print dates and times (run)
#include <fmt/chrono.h> int main() { auto now = std::chrono::system_clock::now(); fmt::print("Date and time: {}\n", now); fmt::print("Time: {:%H:%M}\n", now); }
Output:
Date and time: 2023-12-26 19:10:31.557195597 Time: 19:10
Print a container (run)
#include <vector> #include <fmt/ranges.h> int main() { std::vector<int> v = {1, 2, 3}; fmt::print("{}\n", v); }
Output:
[1, 2, 3]
Check a format string at compile time
std::string s = fmt::format("{:d}", "I am not a number");
This gives a compile-time error in C++20 because d is an invalid format specifier for a string.
Write a file from a single thread
#include <fmt/os.h> int main() { auto out = fmt::output_file("guide.txt"); out.print("Don't {}", "Panic"); }
This can be up to 9 times faster than fprintf.
Print with colors and text styles
#include <fmt/color.h> int main() { fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "Hello, {}!\n", "world"); fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) | fmt::emphasis::underline, "Olá, {}!\n", "Mundo"); fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic, "你好{}!\n", "世界"); }
Output on a modern terminal with Unicode support:
{fmt} can be tens of percent to 20–30 times faster than sprintf and iostreams, especially for numeric formatting. It minimizes dynamic memory allocations and can optionally compile format strings into efficient formatting code.
See format-benchmark and dtoa-benchmark for benchmarks and methodology.
Time per double (smaller is better):
ostringstream and sprintf are omitted because they are an order of magnitude slower than the other methods.
The script bloat-test.py from format-benchmark measures the compile-time and code-size overhead each formatting method adds to application code. It generates 100 translation units and uses printf or its alternative five times in each to simulate a medium-sized project. Library and module build costs are excluded. Results on an Apple M5 Max running macOS 26.6.2 with Apple Clang 21.0.0 (clang-2100.1.1.101), taking the best of three runs, are shown in the following tables.
Optimized build (-O3)
| Method | Compile time, s | Binary size, KiB | Stripped size, KiB |
|---|---|---|---|
| printf | 1.6 | 54 | 50 |
| IOStreams | 25.5 | 98 | 84 |
| fmt 12.2 (headers) | 5.1 | 54 | 50 |
| fmt 12.2 (module) | 3.7 | 59 | 50 |
| Boost Format 1.92 | 49.1 | 517 | 317 |
Using modular {fmt} reduces optimized application-code compile time by 27% without changing the reported stripped binary size.
Non-optimized build
| Method | Compile time, s | Binary size, KiB | Stripped size, KiB |
|---|---|---|---|
| printf | 1.6 | 54 | 50 |
| IOStreams | 26.0 | 88 | 68 |
| fmt 12.2 (headers) | 4.9 | 87 | 84 |
| fmt 12.2 (module) | 3.2 | 77 | 68 |
| Boost Format 1.92 | 35.7 | 741 | 431 |
libc, libc++, libfmt, and libfmt-module were linked as shared libraries to compare formatting function overhead only. Boost Format is header-only.
Notable users include: