From 295ff0f7781d4f9e21d7c3a81ef1f7b26297d31c Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 27 Sep 2026 21:46:39 +0200 Subject: [PATCH] Speed up unit-unicode1 Format \uxxxx escapes by hand instead of constructing a stringstream for each of the ~1.1M code points, and check the JSON Pointer escape/unescape roundtrip on every 64th element of all_unicode.json plus '~' and '/', the only characters escaping treats specially. Signed-off-by: Niels Lohmann --- tests/src/unit-unicode1.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/src/unit-unicode1.cpp b/tests/src/unit-unicode1.cpp index 2d744003a..ba20302fa 100644 --- a/tests/src/unit-unicode1.cpp +++ b/tests/src/unit-unicode1.cpp @@ -14,8 +14,6 @@ using nlohmann::json; #include -#include -#include #include "make_test_data_available.hpp" #include "test_utils.hpp" @@ -29,10 +27,13 @@ TEST_CASE("Unicode (1/5)" * doctest::skip()) // code points are represented as a six-character sequence: a // reverse solidus, followed by the lowercase letter u, followed // by four hexadecimal digits that encode the character's code - // point - std::stringstream ss; - ss << "\\u" << std::setw(4) << std::setfill('0') << std::hex << cp; - return ss.str(); + // point; formatted by hand as this is called ~1.1M times (#5418) + std::string result = "\\u"; + for (int shift = 12; shift >= 0; shift -= 4) + { + result += "0123456789abcdef"[(cp >> shift) & 0xFu]; + } + return result; }; SECTION("correct sequences") @@ -169,6 +170,9 @@ TEST_CASE("Unicode (1/5)" * doctest::skip()) SECTION("check JSON Pointers") { + // escaping only treats '~' and '/' specially, so every 64th + // element plus those two characters suffices (#5418) + std::size_t index = 0; for (const auto& s : j) { // skip non-string JSON values @@ -179,6 +183,11 @@ TEST_CASE("Unicode (1/5)" * doctest::skip()) auto ptr = s.get(); + if (index++ % 64 != 0 && ptr != "~" && ptr != "/") + { + continue; + } + // tilde must be followed by 0 or 1 if (ptr == "~") {