mirror of
https://github.com/nlohmann/json.git
synced 2026-10-22 14:08:13 +00:00
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>