Do not zero the serializer's buffers
Constructing a serializer value-initialized its three buffers (64 + 512 + 1024 bytes). Each is written before it is read and only the part that was written is ever read, so the zeroing was never needed, but it took about 170 instructions per dump(), more than half of the cost of dumping a small value. Apple M1, Apple clang, per dump(): null 325 -> 153 instructions [1,2,3] 629 -> 458 instructions small object (134 B) 2795 -> 2624 instructions, 190 -> 165 ns (-13 %) a 139-byte object, compact: 2763 -> 2596 instructions (-6 %) Large documents are unchanged. Checked with valgrind memcheck over the differential corpus (no use of uninitialized values), and with GCC 13 -Wall -Wextra -Wmaybe-uninitialized at -O0 to -O3 and -Os. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
2 files changed
+16
-8
No files matched your search
Generated
+8
-4
@@ -30226,7 +30226,7 @@ class serializer
|
||||
being threaded through every call to @ref dump, @ref dump_internal and
|
||||
@ref dump_iteratively.
|
||||
*/
|
||||
serializer(output_adapter_protocol<char>& s, const char ichar,
|
||||
serializer(output_adapter_protocol<char>& s, const char ichar, // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init): the buffers are written before they are read
|
||||
const bool pretty_print_ = false,
|
||||
const bool ensure_ascii_ = false,
|
||||
const std::size_t indent_step_ = 0,
|
||||
@@ -32194,11 +32194,15 @@ class serializer
|
||||
/// the output of the serializer (non-owning; the adapter lives at the call site)
|
||||
output_adapter_protocol<char>* o = nullptr;
|
||||
|
||||
// The three buffers below are left uninitialized: they are written before they
|
||||
// are read (only the part written is ever read), and zeroing 1.6 KiB took
|
||||
// more than half of what dumping a small value costs.
|
||||
|
||||
/// a (hopefully) large enough character buffer
|
||||
std::array<char, 64> number_buffer{{}};
|
||||
std::array<char, 64> number_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
|
||||
/// string buffer
|
||||
std::array<char, 512> string_buffer{{}};
|
||||
std::array<char, 512> string_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
|
||||
/// the indentation character
|
||||
const char indent_char;
|
||||
@@ -32218,7 +32222,7 @@ class serializer
|
||||
/// buffer collecting output before it is flushed to the output adapter, so
|
||||
/// that the many small structural writes become few bulk writes
|
||||
static constexpr std::size_t write_buffer_size = 1024;
|
||||
std::array<char, write_buffer_size> write_buffer{{}};
|
||||
std::array<char, write_buffer_size> write_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
||||
/// number of valid bytes currently held in @ref write_buffer
|
||||
std::size_t write_buffer_pos = 0;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user