On Mon, Jul 6, 2026 at 6:29 AM Anlai Lu <[email protected]> wrote:

> This series replaces per-character sputc() with bulk sputn() and
> zero-copy put-area writes when formatting to ostreambuf_iterator.
> Patch 2 adds a _Streambuf_sink that writes directly to a streambuf;
> patch 3 specializes _Iter_sink to use it; patch 1 adds tests.
>
> The design follows review suggestions from Jonathan Wakely (PR111052)
> and Tomasz Kaminski: _Streambuf_sink is a standalone class accepting
> basic_streambuf* directly, and the _Iter_sink specialization is a
> separate commit.
>
Thank you for the patch. I have commented on the 2/3 patch. The
_Streambuf_sink
can expose _M_discarding (and I believe we should), however any _Sink use
with format_to_n cannot do so (as we need to count specialization of
output).
I believe that by moving the counting to the specialization, we can still
handle
that correctly.

Furthermore, if we use _Streambuf_sink, it does not need to count
characters.

>
> Performance (header-overlay A/B, single core, BABA interleave):
>
>   scenario                        16 B    64 B    256 B   1024 B  4096 B
>   print(ostream, "{}", x)         0.96x   0.93x   0.94x   0.96x   0.97x
>   format_to(back_inserter, ...)   1.02x   0.99x   1.00x   1.00x   1.01x
>   format_to(ostreambuf_iter, ...) 1.92x   5.39x  17.52x  54.47x 115.14x
>     with width/padding spec       1.09x   1.08x   1.09x   1.08x   1.27x
>     multi-arg ("_{}_...")         1.16x   1.55x   2.50x   4.39x  14.13x
>     append mode                    -      4.63x  13.69x  32.74x     -
>     to filebuf (/dev/null)        2.01x   5.40x  12.80x  19.73x  22.19x
>     to streambuf w/o put area       -       -    15.95x  21.67x  28.06x
>   format_to_n(ostreambuf_iter,
>     max=len/4, ...)                 -     1.90x   4.87x   6.82x     -
>     max=len*2, ...)                 -     5.14x  17.46x  55.78x     -
>
> Perf stat for the primary fmt_to path:
>
>   len    instr%  cycles%  b_IPC  a_IPC  branch-miss
>   16     66.5%    51.9%   2.24   2.87    44.1%
>   64     33.8%    18.8%   1.60   2.88     0.0%
>   256    12.0%     5.6%   1.36   2.92     0.0%
>   1024    4.1%     1.8%   1.35   3.06     0.0%
>   4096    1.8%     0.8%   1.33   2.93     0.0%
>
> Known limitations:
>  - The print path (std::print to ostream) shows a 3-7% regression
>    from <format> header inflation; it does not use _Streambuf_sink.
>
> Anlai Lu (3):
>   libstdc++: Add tests for format_to with ostreambuf_iterator
>   libstdc++: Add _Streambuf_sink for direct streambuf formatting
>   libstdc++: Specialize _Iter_sink for ostreambuf_iterator
>
>  .../include/bits/streambuf_iterator.h         |  11 +
>  libstdc++-v3/include/std/format               | 212 ++++++++++++++++++
>  libstdc++-v3/include/std/streambuf            |   4 +
>  .../format/functions/format_to_ostreambuf.cc  | 244 +++++++++++++++++++++
>  4 files changed, 471 insertions(+)
>  create mode 100644
> libstdc++-v3/testsuite/std/format/functions/format_to_ostreambuf.cc
>
> base-commit: 5be7b70e769e6e992dbf631cd37e24bd9da9e05e
> --
> 2.34.1
>
>

Reply via email to