On Fri, Jul 24, 2026 at 2:56 PM Anlai Lu <[email protected]> wrote:

> Hi Tomasz,
>
> Tested on Xeon, -O2, core pinned, turbo off.
>
> Perf stat (50M iters):
>
>   den==1 types     instructions   branches
>   ---------------  ------------   --------
>   sys_time_s         -4.2%         -9.6%
>   utc_time_s         -3.8%         -8.7%
>   tai_time_s         -4.2%         -9.6%
>   gps_time_s         -4.2%         -9.6%
>   file_time_s        -4.2%         -9.6%
>   local_time_s       -4.2%         -9.6%
>   zoned_time_s       -2.4%         -4.6%
>   hh_mm_ss_s         -6.0%        -13.6%
>
>   den!=1
>   sys_time_ms        +1.0%         +1.1%
>   utc_time_ms        +1.0%         +1.1%
>   local_time_ms      +1.0%         +1.1%
>   hh_mm_ss_ms        +1.3%         +1.4%
>
> The savings come from the operator<< if constexpr switching to
> the no-locale format_to_n overload, which eliminates the full
> locale chain: vformat_to locale overload, basic_format_context
> locale member.
>
> The den!=1 control types show a small +1.0% in the instruction
> counters that I don't yet have a clear explanation for.  When
> tested in isolation (single type per translation unit) the
> difference disappears completely - isolated sys_time<milliseconds>
> is byte-identical to the baseline.  The +1.0% only appears when
> many types are compiled together, but I haven't been able to
> pin down the exact mechanism.  I need to look into this more, but
> wanted to share the den==1 results now since they are clear.
>
> Happy to send a formal patch after the 16.2 release.
>
This should be a much smaller change, and orthogonal to _Streambuf_patches,
so feel free to send it as soon as you will have it ready.

>
> Thanks again for the review on v4.
>
> Anlai
>
> On Jul 24, 2026, at 15:14, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> On Thu, Jul 23, 2026 at 3:43 PM Tomasz Kaminski <[email protected]>
> wrote:
>
>> Hi,
>>
>> I just pushed the v2/2 patch, thanks again for contribution. As we are
>> closing to 16.2
>> release I will not be able to look at your ostream patches soon (there
>> are some things
>> I want to double-check them).
>>
>> As a side note, in the v4 version that I merged, I removed passing of
>> locale
>> for sys_info, as the output is not really locally depended. I have
>> realized that the same
>> apply to any time_point that uses seconds (or greater precision). I
>> wonder if there would
>> be measurable benefit in defining operator<< for sys_time (utc_time,
>> etc...) as:
>>   if constexpr (Duration::period::den == 1)
>>
> The condition should an or of treat_as_floating_point_v<Rep> || period.den
> == 1, as duration<float>
> contains subseconds even if it represents seconds.
>
> Negated above wrongly, the condition is (!treat_as_floating_point_v<Rep>
&& period.den == 1). So we always
use local for floating point-like durations.

>     chrono_write<64>(os, __t);
>>   else
>>         chrono_write<64>(os, __t, os.getloc());
>> (Maybe we could have time_point_write with above, or time_point overload
>> of chrono_write).
>>
>> I think this also works for zoned_time, as the offset are defined in
>> seconds, so converting
>> will add subseconds. And hh_mm_ss.
>>
>> Is this something you would be interested in taking a look and measuring?
>>
> Yes - definitely worth doing.
>
> Regards,
>> Tomasz
>>
>>
>> On Tue, Jul 14, 2026 at 5:35 AM Anlai Lu <[email protected]> wrote:
>>
>>> PING
>>>
>>> > On Jun 30, 2026, at 20:49, Anlai Lu <[email protected]> wrote:
>>> >
>>> > This is v3 of the patch series.  Performance data: see v2 cover letter.
>>> > Results are unchanged -- same stack-buffer + __ostream_insert approach.
>>> >
>>> > Patch 1 is unchanged from v2.
>>> >
>>> > Changes in Patch 2 from v2:
>>> >
>>> > - Dropped the format string parameter from __chrono_write.
>>> >  _S_empty_fs() is used directly, per Tomasz Kaminski's suggestion.
>>> >  All chrono types now share the same two call forms:
>>> >    __detail::__chrono_write(__os, __arg);
>>> >    __detail::__chrono_write(__os, __arg, __os.getloc());
>>> >
>>> > - Removed __detail::__empty_fmt: no longer needed.
>>> >
>>> > - All remaining operator<< that used basic_stringstream now use
>>> >  __chrono_write (month_day, month_day_last, month_weekday,
>>> >  month_weekday_last, year_month, year_month_day_last,
>>> >  year_month_weekday, year_month_weekday_last, sys_days, local_time).
>>> >
>>> > - The only types not converted: duration (must forward stream flags
>>> >  and precision) and local_info (uses __formatter_chrono_info).
>>> >
>>> > - Uses std::format_to_n (public API) instead of __do_vformat_to_n.
>>> >
>>> > Tested on x86_64-linux-gnu.  libstdc++ testsuite (std/time/*) clean.
>>> > All converted types verified byte-identical across C, en_US, de_DE,
>>> > fr_FR, and zh_CN locales.
>>> >
>>> > Anlai Lu (2):
>>> >  libstdc++: Add stream state tests for chrono operator<<
>>> >  libstdc++: Use __chrono_write via _S_empty_fs for chrono ostream
>>> >    insertion
>>> >
>>> > libstdc++-v3/include/bits/chrono_io.h         | 227 ++++--------------
>>> > .../testsuite/std/time/ostream_insert.cc      | 163 +++++++++++++
>>> > 2 files changed, 212 insertions(+), 178 deletions(-)
>>> > create mode 100644 libstdc++-v3/testsuite/std/time/ostream_insert.cc
>>> >
>>> > --
>>> > 2.34.1
>>>
>>>
>

Reply via email to