mirror of
https://github.com/nlohmann/json.git
synced 2026-10-18 12:08:12 +00:00
Speed up container destruction, iterator access and diff()
- destroy: free a container whose children are all leaves in one go (object of 100k ints: 41.8 -> 17.4 ns/member); the walk stays non-recursive and allocation-free. - iter_impl: check array, then object, before the type switch in ++, *, -> and ==; cold throws moved out of line (range-for over an array 2.5 -> 1.3 ns/element). - diff(): one find per source key, lazily built "add" operations, children compared with == before building their path (diff of citm with 1% changes 1.09 -> 0.70 ms). Output is byte-identical. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
3 files changed
+416
-238
No files matched your search
@@ -280,6 +280,11 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
}
|
||||
|
||||
/// @throw invalid_iterator.214 always
|
||||
JSON_HEDLEY_NEVER_INLINE JSON_HEDLEY_NO_RETURN void throw_compare_different_values() const
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(exception_id::iterators_compare_different_values, "cannot compare iterators of different containers", m_object));
|
||||
}
|
||||
|
||||
JSON_HEDLEY_NO_RETURN void throw_cannot_get_value() const
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(exception_id::iterator_value_unavailable, "cannot get value", m_object));
|
||||
@@ -294,6 +299,18 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(m_object->m_data.m_type == value_t::array))
|
||||
{
|
||||
JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
|
||||
return *m_it.array_iterator;
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(m_object->m_data.m_type == value_t::object))
|
||||
{
|
||||
JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
|
||||
return m_it.object_iterator->second;
|
||||
}
|
||||
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
@@ -338,6 +355,12 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(m_object->m_data.m_type == value_t::array))
|
||||
{
|
||||
JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
|
||||
return &*m_it.array_iterator;
|
||||
}
|
||||
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
@@ -391,6 +414,18 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
{
|
||||
JSON_ASSERT(m_object != nullptr);
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(m_object->m_data.m_type == value_t::array))
|
||||
{
|
||||
++m_it.array_iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(m_object->m_data.m_type == value_t::object))
|
||||
{
|
||||
std::advance(m_it.object_iterator, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
@@ -484,7 +519,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
// if objects are not the same, the comparison is undefined
|
||||
if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
|
||||
{
|
||||
JSON_THROW(invalid_iterator::create(exception_id::iterators_compare_different_values, "cannot compare iterators of different containers", m_object));
|
||||
throw_compare_different_values();
|
||||
}
|
||||
|
||||
// value-initialized forward iterators can be compared, and must compare equal to other value-initialized iterators of the same type #4493
|
||||
@@ -493,6 +528,16 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
|
||||
return true;
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(m_object->m_data.m_type == value_t::array))
|
||||
{
|
||||
return (m_it.array_iterator == other.m_it.array_iterator);
|
||||
}
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(m_object->m_data.m_type == value_t::object))
|
||||
{
|
||||
return (m_it.object_iterator == other.m_it.object_iterator);
|
||||
}
|
||||
|
||||
switch (m_object->m_data.m_type)
|
||||
{
|
||||
case value_t::object:
|
||||
|
||||
Reference in new issue
Block a user