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 >>> >>> >
