Skip to content

Code bloat info actual? #3073

@stgatilov

Description

@stgatilov

The README page advertises fmt as lightweight library. always pointing the user to benchmarks against <fmt/core.h>:

  • Try {fmt} in Compiler Explorer.
  • Small code size both in terms of source code with the minimum configuration consisting of just three files, core.h, format.h and format-inl.h, and compiled code; see Compile time and code bloat

However, it is not said anywhere that benchmarked <fmt/core.h> is not considered default.
In fact, <fmt/core.h> does not support many other of the features advertised:

  • errors in format strings can be reported at compile time
  • Safe printf implementation including the POSIX extension for positional arguments
  • Optional header-only configuration enabled with the FMT_HEADER_ONLY macro

I won't be surprised if extensibility with custom types also does not work with <fmt/core.h>.


In my tests with Visual Studio 2019 optimized build, I noticed that <fmt/format.h> produces 32 times larger object files and takes 10 times more time to compile.
The difference between two modes is huge!

In my measurements, the cost of <fmt/format.h> is 800 KB of object code and 0.5 seconds compilation time (one thread) per one cpp file using it. I got this both on synthetic benchmark and from adding a few fmt calls to all cpp files of a real project.
That's absolutely not lightweight anymore!

This gives the library bad smell.
As if the author of readme is deliberately confusing users with flashy statistics to make the library more popular =)
I totally agree that <fmt/format.h> is a great library with compile-time checks and that <fmt/core.h> is very lightweight, but readme should say straight that these two qualities don't combine, and that user has to choose.

UPDATE: I got very slow compilation because of fmt::format_to_n + <fmt/format.h> combo (more info below).


Also note that the cited compilation time benchmark from tinyformat does not use precompiled headers.
So the reported times include time of parsing, and thus don't reflect the best-practices real world usage.

I'm not sure about GCC/Clang, but on MSVC parsing usually takes the majority of time without PCH, but it can be completely removed by adding libraries to precompiled header.
This explains why boost looks so bad (including boost without PCH is absurd), and why printf+string looks so much slower than printf (including STL in PCH is obvious, isn't it?).

Just to clarify: I added fmt headers to precompiled headers in my benchmarks of fmt.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions