mirror of
https://github.com/nlohmann/json.git
synced 2026-10-23 22:38:55 +00:00
Collect the writes of the adapter sink and pass them on in blocks
to_cbor(j, o) and its siblings with a std::string, a std::vector or a std::ostream go through output_adapter_sink, where every write is a virtual call, and for a stream a call with a sentry on top. That costs more than encoding the few bytes of most values, which is why those overloads were 1.8 to 3 times slower than the vector-returning ones. The sink now keeps a 1 KiB buffer and passes it on when it is full, when a write is larger than the space left (a payload of a KiB or more goes directly), or when binary_writer::flush() is called at the end of the to_* function. Everything reaches the adapter in the same order. The destructor flushes what is left, so a value that throws (invalid UTF-8 with the strict handler) leaves the same partial output as before; only flush() can report an error of the adapter, as a destructor must not throw. Instructions per call (Linux, GCC 13, thousands), to_*(j, std::string&): twitter cbor 4952 -> 3356, twitter ubjson 6762 -> 4647, twitter bson 5518 -> 4704, citm_catalog cbor 10404 -> 7090; to_*(j, std::ostream&): twitter cbor 9178 -> 3844, twitter ubjson 11974 -> 5129, citm_catalog cbor 18374 -> 7554. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
4 files changed
+308
-50
No files matched your search
@@ -123,9 +123,22 @@ class binary_writer
|
||||
template < typename SinkType = OutputSinkType,
|
||||
typename std::enable_if < std::is_constructible<SinkType, output_adapter_t<CharType>>::value, int >::type = 0 >
|
||||
explicit binary_writer(output_adapter_t<CharType> adapter, const error_handler_t error_handler_ = binary_writer_default_error_handler())
|
||||
: oa(SinkType(std::move(adapter))), error_handler(error_handler_)
|
||||
: oa(std::move(adapter)), error_handler(error_handler_)
|
||||
{}
|
||||
|
||||
/*!
|
||||
@brief pass on everything written so far to the output adapter
|
||||
|
||||
A writer over an output_adapter_sink buffers what it writes; this has to
|
||||
be called after the last write, or the buffered end is only passed on, and
|
||||
an error of the adapter lost, when the writer is destroyed. A writer over
|
||||
an output_vector_sink writes straight into the vector.
|
||||
*/
|
||||
void flush()
|
||||
{
|
||||
oa.flush();
|
||||
}
|
||||
|
||||
/*!
|
||||
@param[in] j JSON value to serialize
|
||||
@throw type_error.316 if a string value or an object key is not valid
|
||||
|
||||
Reference in new issue
Block a user