diff --git a/README.rst b/README.rst index 7511d164..69267cb2 100644 --- a/README.rst +++ b/README.rst @@ -57,21 +57,14 @@ See the `documentation `_ for more details. Examples -------- -This prints ``Hello, world!`` to stdout: +Print ``Hello, world!`` to ``stdout``: .. code:: c++ fmt::print("Hello, {}!", "world"); // uses Python-like format string syntax fmt::printf("Hello, %s!", "world"); // uses printf format string syntax -Arguments can be accessed by position and arguments' indices can be repeated: - -.. code:: c++ - - std::string s = fmt::format("{0}{1}{0}", "abra", "cad"); - // s == "abracadabra" - -Format strings can be checked at compile time: +Check a format string at compile time: .. code:: c++ @@ -94,7 +87,7 @@ Format strings can be checked at compile time: context_.on_error("argument index out of range"); ^ -{fmt} can be used as a safe portable replacement for ``itoa`` +Use {fmt} as a safe portable replacement for ``itoa`` (`godbolt `_): .. code:: c++ @@ -129,7 +122,7 @@ Formatting of user-defined types is supported via a simple std::string s = fmt::format("The date is {}", date{2012, 12, 9}); // s == "The date is 2012-12-9" -You can create your own functions similar to `format +Create your own functions similar to `format `_ and `print `_ which take arbitrary arguments (`godbolt `_): @@ -152,6 +145,108 @@ Note that ``vreport_error`` is not parameterized on argument types which can improve compile times and reduce code size compared to fully parameterized version. +Benchmarks +---------- + +Speed tests +~~~~~~~~~~~ + +================= ============= =========== +Library Method Run Time, s +================= ============= =========== +libc printf 1.01 +libc++ std::ostream 3.04 +{fmt} 1632f72 fmt::print 0.86 +tinyformat 2.0.1 tfm::printf 3.23 +Boost Format 1.67 boost::format 7.98 +Folly Format folly::format 2.23 +================= ============= =========== + +{fmt} is the fastest of the benchmarked methods, ~17% faster than ``printf``. + +The above results were generated by building ``tinyformat_test.cpp`` on macOS +10.14.3 with ``clang++ -O3 -DSPEED_TEST -DHAVE_FORMAT``, and taking the best of +three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` +or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for +further details refer to the `source +`_. + +Compile time and code bloat +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The script `bloat-test.py +`_ +from `format-benchmark `_ +tests compile time and code bloat for nontrivial projects. +It generates 100 translation units and uses ``printf()`` or its alternative +five times in each to simulate a medium sized project. The resulting +executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), +macOS Sierra, best of three) is shown in the following tables. + +**Optimized build (-O3)** + +============= =============== ==================== ================== +Method Compile Time, s Executable size, KiB Stripped size, KiB +============= =============== ==================== ================== +printf 2.6 29 26 +printf+string 16.4 29 26 +iostreams 31.1 59 55 +{fmt} 19.0 37 34 +tinyformat 44.0 103 97 +Boost Format 91.9 226 203 +Folly Format 115.7 101 88 +============= =============== ==================== ================== + +As you can see, {fmt} has 60% less overhead in terms of resulting binary code +size compared to iostreams and comes pretty close to ``printf``. Boost Format +and Folly Format have the largest overheads. + +``printf+string`` is the same as ``printf`` but with extra ```` +include to measure the overhead of the latter. + +**Non-optimized build** + +============= =============== ==================== ================== +Method Compile Time, s Executable size, KiB Stripped size, KiB +============= =============== ==================== ================== +printf 2.2 33 30 +printf+string 16.0 33 30 +iostreams 28.3 56 52 +{fmt} 18.2 59 50 +tinyformat 32.6 88 82 +Boost Format 54.1 365 303 +Folly Format 79.9 445 430 +============= =============== ==================== ================== + +``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared libraries to +compare formatting function overhead only. Boost Format and tinyformat are +header-only libraries so they don't provide any linkage options. + +Running the tests +~~~~~~~~~~~~~~~~~ + +Please refer to `Building the library`__ for the instructions on how to build +the library and run the unit tests. + +__ http://fmtlib.net/latest/usage.html#building-the-library + +Benchmarks reside in a separate repository, +`format-benchmarks `_, +so to run the benchmarks you first need to clone this repository and +generate Makefiles with CMake:: + + $ git clone --recursive https://github.com/fmtlib/format-benchmark.git + $ cd format-benchmark + $ cmake . + +Then you can run the speed test:: + + $ make speed-test + +or the bloat test:: + + $ make bloat-test + Projects using this library --------------------------- @@ -331,108 +426,6 @@ than ``fmt::format_int`` on Karma's own benchmark, see `Fast integer to string conversion in C++ `_. -Benchmarks ----------- - -Speed tests -~~~~~~~~~~~ - -================= ============= =========== -Library Method Run Time, s -================= ============= =========== -libc printf 1.01 -libc++ std::ostream 3.04 -fmt 1632f72 fmt::print 0.86 -tinyformat 2.0.1 tfm::printf 3.23 -Boost Format 1.67 boost::format 7.98 -Folly Format folly::format 2.23 -================= ============= =========== - -{fmt} is the fastest of the benchmarked methods, ~17% faster than ``printf``. - -The above results were generated by building ``tinyformat_test.cpp`` on macOS -10.14.3 with ``clang++ -O3 -DSPEED_TEST -DHAVE_FORMAT``, and taking the best of -three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` -or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for -further details refer to the `source -`_. - -Compile time and code bloat -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The script `bloat-test.py -`_ -from `format-benchmark `_ -tests compile time and code bloat for nontrivial projects. -It generates 100 translation units and uses ``printf()`` or its alternative -five times in each to simulate a medium sized project. The resulting -executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), -macOS Sierra, best of three) is shown in the following tables. - -**Optimized build (-O3)** - -============= =============== ==================== ================== -Method Compile Time, s Executable size, KiB Stripped size, KiB -============= =============== ==================== ================== -printf 2.6 29 26 -printf+string 16.4 29 26 -iostreams 31.1 59 55 -{fmt} 19.0 37 34 -tinyformat 44.0 103 97 -Boost Format 91.9 226 203 -Folly Format 115.7 101 88 -============= =============== ==================== ================== - -As you can see, {fmt} has 60% less overhead in terms of resulting binary code -size compared to iostreams and comes pretty close to ``printf``. Boost Format -and Folly Format have the largest overheads. - -``printf+string`` is the same as ``printf`` but with extra ```` -include to measure the overhead of the latter. - -**Non-optimized build** - -============= =============== ==================== ================== -Method Compile Time, s Executable size, KiB Stripped size, KiB -============= =============== ==================== ================== -printf 2.2 33 30 -printf+string 16.0 33 30 -iostreams 28.3 56 52 -{fmt} 18.2 59 50 -tinyformat 32.6 88 82 -Boost Format 54.1 365 303 -Folly Format 79.9 445 430 -============= =============== ==================== ================== - -``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared libraries to -compare formatting function overhead only. Boost Format and tinyformat are -header-only libraries so they don't provide any linkage options. - -Running the tests -~~~~~~~~~~~~~~~~~ - -Please refer to `Building the library`__ for the instructions on how to build -the library and run the unit tests. - -__ http://fmtlib.net/latest/usage.html#building-the-library - -Benchmarks reside in a separate repository, -`format-benchmarks `_, -so to run the benchmarks you first need to clone this repository and -generate Makefiles with CMake:: - - $ git clone --recursive https://github.com/fmtlib/format-benchmark.git - $ cd format-benchmark - $ cmake . - -Then you can run the speed test:: - - $ make speed-test - -or the bloat test:: - - $ make bloat-test - FAQ --- @@ -459,7 +452,7 @@ A: use ``std::tuple``: License ------- -fmt is distributed under the BSD `license +{fmt} is distributed under the BSD `license `_. The `Format String Syntax @@ -475,7 +468,7 @@ It only applies if you distribute the documentation of fmt. Acknowledgments --------------- -The fmt library is maintained by Victor Zverovich (`vitaut +The {fmt} library is maintained by Victor Zverovich (`vitaut `_) and Jonathan Müller (`foonathan `_) with contributions from many other people. See `Contributors `_ and