Question Details

No question body available.

Tags

c++ performance c++-chrono stdformat

Answers (3)

Accepted Answer Available
Accepted Answer
August 5, 2025 Score: 6 Rep: 853 Quality: Expert Completeness: 100%

There are two main reasons why the "new" version is significantly slower than the "old" one:

  • std::chrono::currentzone()->tolocal(now).

This performs a full IANA/Win32 time zone lookup and applies all historical DST transitions. On Windows, it calls Win32 Time Zone API under the hood; on POSIX, it reads TZDB files. Even if the data is cached after the first lookup, each call still binary-searches in-memory tables and applies offset calculations. This is modern solution that avoids many problems old one had. By contrast, localtimes(&loc, &tc) is just a thin wrapper over the CRT's process-wide tzinfo table, which is simpler and much faster to work with.

  • std::format("{0:%F} {0:%R}:{0:%S}", //);

std::format uses a generic formatting engine that dispatches through std::formatter specializations for dates, performing locale checks, width and fill handling, and so on. Even though the format string is parsed at compile-time, the runtime still must traverse formatting tables and apply all formatting rules. So, even known compilers optimize a lot, std::puttime(&loc, "%F %T.") is still faster, because it is time-specific formatting wrapping over strftime, which is plain C and optimized heavily for date and time formats.

Generally speaking, "new" versions is modern, more portable solution that comes with a cost of performance.

If the performance is strictly the goal, "old" solution still can be optimized further down by:

  • Avoiding std::stringstream entirely. It can be replaced with std::formatto or fmt::memorybuffer. For maximal performance, consider snprintf into a fixed buffer directly;
  • Caching tzinfo and statically allocating char buffers to avoid dynamic allocation at all.

But each of these optimizations comes with a cost of reduced readability and scalability of the code.

August 5, 2025 Score: 0 Rep: 134 Quality: Low Completeness: 40%

currentzone()->tolocal(now) does time zone database lookups and DST calculations.
That's why it takes more time than localtime_s .

std::format is slower because of heavy formatting logics.

August 6, 2025 Score: 0 Rep: 33 Quality: Low Completeness: 40%

I tried optimizing the time zone conversion by saving the offset between UTC and local time at startup of my program (which is good enough for my use). This seems to be very fast (as expected).

Unfortunately the MS compiler/runtime lib does not seem to have a good implementation of std::format since it is consistently slower than puttime (at least twice the cost).

I did a little experiment in QuickBench (here if anyone is interested) Here the fixed offset + std::format version is a bit faster. Unfortunately (for me) this cannot be replicated in Visual Studio where std::format is too slow to compete.

I think I will have to stick with the current implementation using puttime :(

But thanks for all you input!