iter_impl: keep the type-dependent initialization in the constructor

The check is not needed for correctness (m_it is value-initialized), but
without it GCC 13 generates slower iteration loops: a recursive walk over
a parsed document takes 0.5-2.7 % longer (callgrind: +1.9 % instructions
on twitter.json, +0.95 % on canada.json). Clang generates identical code
either way. See the measurements in #6005.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-11-02 10:05:54 +01:00
1 parent 2ac0851157
commit 7196bc5b22
2 files changed
+34 -4

No files matched your search

+17 -2
View File
@@ -24063,8 +24063,23 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
explicit iter_impl(pointer object) noexcept : m_object(object)
{
JSON_ASSERT(m_object != nullptr);
// m_it is value-initialized: its iterators are singular, and the
// primitive iterator is in its "uninitialized" state
// m_it is already value-initialized, so this is not needed for
// correctness; it is kept because GCC generates faster loops with it
// (iterating a parsed document is 0.5-2.7 % slower without it, #6005)
if (m_object->is_object())
{
m_it.object_iterator = typename object_t::iterator();
}
else if (m_object->is_array())
{
m_it.array_iterator = typename array_t::iterator();
}
else
{
// primitive (is_primitive(), including discarded)
m_it.primitive_iterator = primitive_iterator_t();
}
}
/*!