Commit Graph

3 Commits

Author SHA1 Message Date
Mark de Wever fb9a692be5 [libc++][format][4/6] Improve formatted_size.
Use a specialized "buffer" to count the number of insertions instead of
using a `string` as storage type.

Depends on D110497.

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D110498
2022-04-09 09:36:29 +02:00
Mark de Wever 889302292b [libc++][format][3/6] Adds a __container_buffer.
Instead of writing every character directly into the container by using
a `back_insert_iterator` the data is buffered in an `array`. This buffer
is then inserted to the container by calling its `insert` member function.

Since there's no guarantee every container's `insert` behaves properly
containers need to opt-in to this behaviour. The appropriate standard
containers opt-in to this behaviour.

This change improves the performance of the format functions that use a
`back_insert_iterator`.

Depends on D110495

Reviewed By: ldionne, vitaut, #libc

Differential Revision: https://reviews.llvm.org/D110497
2022-04-09 09:35:48 +02:00
Mark de Wever 555214cbcc [libc++][format][2/6] Adds a __output_iterator.
Instead of using a temporary `string` in `__vformat_to_wrapped` use a new
generic iterator. This aids to reduce the number of template instantions
and avoids using a `string` to buffer the entire formatted output.

This changes the type of `format_context` and `wformat_context`, this can
still be done since the code isn't ABI stable yet.

Several approaches have been evaluated:
- Using a __output_buffer base class with:
  - a put function to store the buffer in its internal buffer
  - a virtual flush function to copy the internal buffer to the output
- Using a `function` to forward the output operation to the output buffer,
  much like the next method.
- Using a type erased function point to store the data in the buffer.
The last version resulted in the best performance. For some cases there's
still a loss of speed over the original method. This loss many becomes
apparent when large strings are copied to a pointer like iterator, before
the compiler optimized this using `memcpy`.

Reviewed By: ldionne, vitaut, #libc

Differential Revision: https://reviews.llvm.org/D110495
2022-03-26 16:48:01 +01:00