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:
2 files changed
+34
-4
No files matched your search
@@ -107,8 +107,23 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
explicit iter_impl(pointer object) noexcept : m_object(object)
|
explicit iter_impl(pointer object) noexcept : m_object(object)
|
||||||
{
|
{
|
||||||
JSON_ASSERT(m_object != nullptr);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
Generated
+17
-2
@@ -24063,8 +24063,23 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
|||||||
explicit iter_impl(pointer object) noexcept : m_object(object)
|
explicit iter_impl(pointer object) noexcept : m_object(object)
|
||||||
{
|
{
|
||||||
JSON_ASSERT(m_object != nullptr);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
Reference in new issue
Block a user