2012-12-07 16:26:46 +00:00
|
|
|
format
|
|
|
|
======
|
|
|
|
|
2012-12-07 22:18:37 +00:00
|
|
|
Format is a C++ library that provides printf-like formatting functionality.
|
|
|
|
|
|
|
|
Features
|
|
|
|
--------
|
|
|
|
|
|
|
|
* Format string syntax similar to the one used by `str.format
|
|
|
|
<http://docs.python.org/2/library/stdtypes.html#str.format>`__ in Python.
|
|
|
|
* High speed: performance of the current proof-of-concept implementation
|
2012-12-07 22:22:24 +00:00
|
|
|
is close to that of iostreams (see `Speed tests`_).
|
2012-12-07 22:18:37 +00:00
|
|
|
* Small code size both in terms of source code (format consists of a single
|
2012-12-07 22:22:24 +00:00
|
|
|
header file and a single source file) and compiled code
|
|
|
|
(see `Compile time and code bloat`_).
|
2012-12-07 22:18:37 +00:00
|
|
|
* Easy deployment: small self-contained code base, no external dependencies,
|
|
|
|
permissive license.
|
|
|
|
* Support for user-defined types.
|
|
|
|
|
|
|
|
Example
|
|
|
|
-------
|
|
|
|
|
|
|
|
fmt::Print("Hello, {0}!") << "world";
|
2012-12-07 21:20:50 +00:00
|
|
|
|
|
|
|
Benchmarks
|
|
|
|
----------
|
|
|
|
|
|
|
|
Compile time and code bloat
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
The script ``bloat_test.sh`` from the `tinyformat
|
|
|
|
<https://github.com/c42f/tinyformat>`__ repository 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
|
|
|
|
(g++-4.7.2, Ubuntu GNU/Linux 12.10, best of three) is shown in the following
|
|
|
|
tables.
|
|
|
|
|
|
|
|
**Non-optimized build**
|
|
|
|
|
|
|
|
====================== ================== ==========================
|
|
|
|
test name total compile time executable size (stripped)
|
|
|
|
====================== ================== ==========================
|
|
|
|
libc printf 2.8s 44K (32K)
|
|
|
|
std::ostream 12.9s 84K (60K)
|
|
|
|
format 16.0s 152K (128K)
|
|
|
|
tinyformat 20.6s 240K (200K)
|
|
|
|
boost::format 76.0s 888K (780K)
|
|
|
|
====================== ================== ==========================
|
|
|
|
|
|
|
|
**Optimized build (-O3)**
|
|
|
|
|
|
|
|
====================== ================== ==========================
|
|
|
|
test name total compile time executable size (stripped)
|
|
|
|
====================== ================== ==========================
|
|
|
|
libc printf 3.5s 40K (28K)
|
|
|
|
std::ostream 14.1s 88K (64K)
|
|
|
|
format 25.1s 552K (536K)
|
|
|
|
tinyformat 56.3s 200K (164K)
|
|
|
|
boost::format 169.4s 1.7M (1.6M)
|
|
|
|
====================== ================== ==========================
|
|
|
|
|
|
|
|
Printf and std::ostream win here which is not surprising considering
|
|
|
|
that they are included in the standard library. Tinyformat has somewhat
|
|
|
|
slower compilation times compared to format. Interestingly optimized
|
|
|
|
executable size is smaller with tinyformat then with format and for
|
2012-12-07 22:18:37 +00:00
|
|
|
non-optimized build its the other way around. Boost::format has by far
|
|
|
|
the largest overheads.
|
2012-12-07 21:20:50 +00:00
|
|
|
|
|
|
|
Speed tests
|
|
|
|
~~~~~~~~~~~
|
|
|
|
|
|
|
|
The following speed tests results were generated by building
|
|
|
|
``tinyformat_test.cpp`` on Ubuntu GNU/Linux 12.10 with
|
|
|
|
``g++-4.7.2 -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 2000000 times with output sent to ``/dev/null``; for
|
|
|
|
further details see the `source
|
|
|
|
<https://github.com/vitaut/tinyformat/blob/master/tinyformat_test.cpp>`__.
|
|
|
|
|
|
|
|
============== ========
|
|
|
|
test name run time
|
|
|
|
============== ========
|
|
|
|
libc printf 1.26s
|
|
|
|
std::ostream 2.02s
|
|
|
|
format 2.20s
|
|
|
|
tinyformat 2.51s
|
|
|
|
boost::format 10.40s
|
|
|
|
============== ========
|
|
|
|
|
|
|
|
As you can see boost::format is much slower than the alternative methods; this
|
|
|
|
is confirmed by `other tests <http://accu.org/index.php/journals/1539>`__.
|
|
|
|
Tinyformat is quite good coming close to iostreams. Unfortunately tinyformat
|
|
|
|
cannot be faster than the iostreams because it uses them internally.
|
2012-12-07 21:33:08 +00:00
|
|
|
Performance of format is close to that of std::ostream but there is a room for
|
|
|
|
improvement since format is not based on iostreams.
|
2012-12-07 21:20:50 +00:00
|
|
|
|
|
|
|
Running the tests
|
|
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
To run the tests you first need to get the format repository with submodules::
|
|
|
|
|
|
|
|
$ git clone --recursive git://github.com/vitaut/format.git
|
|
|
|
|
2012-12-07 21:33:08 +00:00
|
|
|
Then go to the format directory and generate Makefiles with
|
|
|
|
`CMake <http://www.cmake.org/>`__::
|
2012-12-07 21:20:50 +00:00
|
|
|
|
|
|
|
$ cd format
|
|
|
|
$ cmake .
|
|
|
|
|
|
|
|
Next use the following commands to run the speed test::
|
|
|
|
|
|
|
|
$ make speed_test
|
|
|
|
|
|
|
|
or the bloat test::
|
|
|
|
|
|
|
|
$ make bloat_test
|
|
|
|
|
|
|
|
Acknowledgments
|
|
|
|
---------------
|
|
|
|
|
|
|
|
The benchmark section of this readme file and the performance tests are taken
|
|
|
|
from the excellent `tinyformat <https://github.com/c42f/tinyformat>`__ library
|
|
|
|
written by Chris Foster. boost::format is acknowledged transitively since
|
2012-12-07 21:33:08 +00:00
|
|
|
it had some influence on tinyformat. Some ideas used in the implementation
|
|
|
|
are borrowed from `Loki <http://loki-lib.sourceforge.net/>`__ SafeFormat and
|
|
|
|
`Diagnostic API <http://clang.llvm.org/doxygen/classclang_1_1Diagnostic.html>`__
|
|
|
|
in `Clang <http://clang.llvm.org/>`__.
|