Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/tests/SelfTest
diff options
context:
space:
mode:
authorMartin Hořeňovský2025-08-21 23:36:22 +0200
committerMartin Hořeňovský2025-08-22 17:00:40 +0200
commitfb2e4fbe413824a5cad4101c0e94cb10b7828f0d (patch)
tree8da4e08aeeea0d85f71f5db767a832085a9f8666 /tests/SelfTest
parent78a9518a2847f82cb65124d65eaf0b0be8d90cdc (diff)
downloadcatch3-fb2e4fbe413824a5cad4101c0e94cb10b7828f0d.tar.gz
Improve performance of writing JSON values
The old code was exceedingly simple, as it went char-by-char and decided whether to write it to the output stream as-is, or escaped. This caused a _lot_ of stream writes of individual characters. The new code instead looks for characters that need escaping, and bulk-writes the non-escaped characters in between them. This leads to about the same performance for strings that comprise of only escaped characters, and 3-10x improvement for strings without any escaping needed. In practice, we should expect the former rather than the latter, but this is still nice improvement.
Diffstat (limited to 'tests/SelfTest')
-rw-r--r--tests/SelfTest/IntrospectiveTests/Json.tests.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/tests/SelfTest/IntrospectiveTests/Json.tests.cpp b/tests/SelfTest/IntrospectiveTests/Json.tests.cpp
index bee85c99..fae1c843 100644
--- a/tests/SelfTest/IntrospectiveTests/Json.tests.cpp
+++ b/tests/SelfTest/IntrospectiveTests/Json.tests.cpp
@@ -7,6 +7,8 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/catch_test_macros.hpp>
+#include <catch2/benchmark/catch_benchmark.hpp>
+#include <catch2/generators/catch_generators.hpp>
#include <catch2/internal/catch_jsonwriter.hpp>
#include <catch2/matchers/catch_matchers_string.hpp>
@@ -17,7 +19,6 @@ namespace {
static std::ostream& operator<<( std::ostream& os, Custom const& ) {
return os << "custom";
}
-} // namespace
TEST_CASE( "JsonWriter", "[JSON][JsonWriter]" ) {
@@ -150,3 +151,28 @@ TEST_CASE( "JsonWriter escapes characters in strings properly", "[JsonWriter]" )
REQUIRE( sstream.str() == "\"\\\\/\\t\\r\\n\"" );
}
}
+
+TEST_CASE( "JsonWriter benchmarks", "[JsonWriter][!benchmark]" ) {
+ const auto input_length = GENERATE( as<size_t>{}, 10, 100, 10'000 );
+ std::string test_input( input_length, 'a' );
+ BENCHMARK_ADVANCED( "write string, no-escaping, len=" +
+ std::to_string( input_length ) )(
+ Catch::Benchmark::Chronometer meter ) {
+ std::stringstream sstream;
+ meter.measure( [&]( int ) {
+ Catch::JsonValueWriter( sstream ).write( test_input );
+ } );
+ };
+
+ std::string escape_input( input_length, '\b' );
+ BENCHMARK_ADVANCED( "write string, all-escaped, len=" +
+ std::to_string( input_length ) )(
+ Catch::Benchmark::Chronometer meter ) {
+ std::stringstream sstream;
+ meter.measure( [&]( int ) {
+ Catch::JsonValueWriter( sstream ).write( escape_input );
+ } );
+ };
+}
+
+} // namespace