[llvm-branch-commits] [libcxx] [libc++][format][3/7] Improves std::format performance. (PR #101817)
Louis Dionne via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 13 10:11:27 PDT 2024
================
@@ -58,23 +59,156 @@ namespace __format {
/// This helper is used together with the @ref back_insert_iterator to offer
/// type-erasure for the formatting functions. This reduces the number to
/// template instantiations.
+///
+/// The design of the class is being changed to improve performance and do some
+/// code cleanups.
+/// The original design (as shipped up to LLVM-19) uses the following design:
+/// - There is an external object that connects the buffer to the output.
+/// - The class constructor stores a function pointer to a grow function and a
+/// type-erased pointer to the object that does the grow.
+/// - When writing data to the buffer would exceed the external buffer's
+/// capacity it requests the external buffer to flush its contents.
+///
+/// The new design tries to solve some issues with the current design:
+/// - The buffer used is a fixed-size buffer, benchmarking shows that using a
+/// dynamic allocated buffer has performance benefits.
+/// - Implementing P3107R5 "Permit an efficient implementation of std::print"
+/// is not trivial with the current buffers. Using the code from this series
+/// makes it trivial.
+///
+/// This class is ABI-tagged, still the new design does not change the size of
+/// objects of this class.
+///
+/// The new design contains information regarding format_to_n changes, these
+/// will be implemented in follow-up patch.
+///
+/// The new design is the following.
+/// - There is an external object that connects the buffer to the output.
+/// - This buffer object:
+/// - inherits publicly from this class.
+/// - has a static or dynamic buffer.
+/// - has a static member function to make space in its buffer write
+/// operations. This can be done by increasing the size of the internal
+/// buffer or by writing the contents of the buffer to the output iterator.
+///
+/// This member function is a constructor argument, so its name is not
+/// fixed. The code uses the name __prepare_write.
+/// - The number of output code units can be limited by a __max_output_size
+/// object. This is used in format_to_n This object:
+/// - Contains the maximum number of code units to be written.
+/// - Contains the number of code units that are requested to be written.
+/// This number is returned to the user of format_to_n.
+/// - The write functions call objects __request_write member function.
+/// This function:
+/// - Updates the number of code units that are requested to be written.
+/// - Returns the number of code units that can be written without
+/// exceeding the maximum number of code units to be written.
+///
+/// Documentation for the buffer usage members:
+/// - __ptr_ the start of the buffer.
+/// - __capacity_ the number of code units that can be written.
+/// This means [__ptr_, __ptr_ + __capacity_) is a valid range to write to.
+/// - __size_ the number of code units written in the buffer. The next code
+/// unit will be written at __ptr_ + __size_. This __size_ may NOT contain
+/// the total number of code units written by the __output_buffer. Whether or
+/// not it does depends on the sub-class used. Typically the total number of
+/// code units written is not interesting. It is interesting for format_to_n
+/// which has its own way to track this number.
+///
+/// Documentation for the buffer changes function:
+/// The subclasses have a function with the following signature:
+///
+/// static void __prepare_write(
+/// __output_buffer<_CharT>& __buffer, size_t __code_units);
+///
+/// This function is called when a write function writes more code units than
+/// the buffer' available space. When an __max_output_size object is provided
+/// the number of code units is the number of code units returned from
+/// __max_output_size::__request_write function.
+///
+/// - The __buffer contains *this. Since the class containing this function
+/// inherits from __output_buffer it's save to cast it to the subclass being
----------------
ldionne wrote:
```suggestion
/// inherits from __output_buffer it's safe to cast it to the subclass being
```
https://github.com/llvm/llvm-project/pull/101817
More information about the llvm-branch-commits
mailing list