From 97ce0e1e5de3c4f355ec0500396fee84753a12e5 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Fri, 6 Nov 2026 17:44:50 +0100 Subject: [PATCH] docs: blog post: comparing already passes the depth; copying measured slower without the counter operator== walks the standard containers itself and passes the depth as an argument (#5840). A copy that does the same, inserting element by element, measured 4-16% slower on an M1 Max with Apple clang, so copying keeps the thread_local counter. Signed-off-by: Niels Lohmann --- docs/mkdocs/docs/home/blog/how_3_13_0_got_faster.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/mkdocs/docs/home/blog/how_3_13_0_got_faster.md b/docs/mkdocs/docs/home/blog/how_3_13_0_got_faster.md index 299278e30..dd2456e7b 100644 --- a/docs/mkdocs/docs/home/blog/how_3_13_0_got_faster.md +++ b/docs/mkdocs/docs/home/blog/how_3_13_0_got_faster.md @@ -1108,11 +1108,12 @@ static void destroy_bounded(basic_json& v, std::size_t depth) noexcept

Bounded recursion: recursive down to 128 levels, iterative below.

The first 128 levels run the old recursive code, and only below that does an explicit stack, or the walk below, take -over. A document nested less deeply pays one comparison per container. Copying and comparing recurse through the -containers: `std::vector`'s and `std::map`'s copy constructors and `operator==` call those of the elements, whose -signatures are fixed, so no depth argument can be passed down. Passing one would mean copying or comparing element by -element ourselves, which is what the explicit stack below the limit does. They count the levels in a `thread_local` -counter, about ten nanoseconds per copy of a small object. +over. A document nested less deeply pays one comparison per container. Comparing walks `std::vector` and `std::map` +itself and passes the depth as an argument. Copying can't do that cheaply: the containers' copy constructors call ours +for every element, and a copy that inserts element by element so that it can pass the depth measured 4–16% slower, +because `std::map`'s own copy clones its tree without comparing a single key. So copying counts the levels in a +`thread_local` counter instead, about ten nanoseconds per copy of a small object, and so does comparing for custom +container types. ### Destroying without a stack