Search once for a new object member in unflatten() and j[json_pointer]
object_member() looked a key up and, if it was missing, inserted it with operator[], which searches again. Objects that can find the position of a key and insert there (std::map) now do both with one search; other object types are unchanged. A key that exists is not copied, as before. unflatten() (instructions on macOS, Linux Ir GCC 13 / Clang 18): twitter 25.8M -> 24.2M, 24.9M -> 21.8M / 24.8M -> 21.5M; citm_catalog 43.4M -> 43.5M, 38.9M -> 37.0M / 39.6M -> 37.5M; canada unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
2 files changed
+52
-2
No files matched your search
@@ -482,8 +482,27 @@ class json_pointer
|
||||
}
|
||||
|
||||
/// @brief object member access with a key that is only copied if it is inserted
|
||||
///
|
||||
/// Objects that can find the position of a key and insert there
|
||||
/// (std::map) search once, others look the key up and add it if it is missing.
|
||||
template<typename BasicJsonType>
|
||||
static BasicJsonType& object_member(BasicJsonType& object, const string_t& key)
|
||||
static auto object_member_impl(BasicJsonType& object, const string_t& key, detail::priority_tag<1> /*unused*/)
|
||||
-> decltype(object.m_data.m_value.object->emplace_hint(object.m_data.m_value.object->lower_bound(key), key, nullptr), std::declval<BasicJsonType&>())
|
||||
{
|
||||
auto& members = *object.m_data.m_value.object;
|
||||
auto it = members.lower_bound(key);
|
||||
if (it != members.end() && !members.key_comp()(key, it->first))
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const auto old_capacity = object.container_capacity();
|
||||
it = members.emplace_hint(it, key, nullptr);
|
||||
return object.set_parent_after_insert(it->second, old_capacity);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static BasicJsonType& object_member_impl(BasicJsonType& object, const string_t& key, detail::priority_tag<0> /*unused*/)
|
||||
{
|
||||
auto& members = *object.m_data.m_value.object;
|
||||
const auto it = members.find(key);
|
||||
@@ -494,6 +513,12 @@ class json_pointer
|
||||
return object.operator[](key);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static BasicJsonType& object_member(BasicJsonType& object, const string_t& key)
|
||||
{
|
||||
return object_member_impl(object, key, detail::priority_tag<1> {});
|
||||
}
|
||||
|
||||
JSON_PRIVATE_UNLESS_TESTED:
|
||||
json_pointer top() const
|
||||
{
|
||||
|
||||
Generated
+26
-1
@@ -22832,8 +22832,27 @@ class json_pointer
|
||||
}
|
||||
|
||||
/// @brief object member access with a key that is only copied if it is inserted
|
||||
///
|
||||
/// Objects that can find the position of a key and insert there
|
||||
/// (std::map) search once, others look the key up and add it if it is missing.
|
||||
template<typename BasicJsonType>
|
||||
static BasicJsonType& object_member(BasicJsonType& object, const string_t& key)
|
||||
static auto object_member_impl(BasicJsonType& object, const string_t& key, detail::priority_tag<1> /*unused*/)
|
||||
-> decltype(object.m_data.m_value.object->emplace_hint(object.m_data.m_value.object->lower_bound(key), key, nullptr), std::declval<BasicJsonType&>())
|
||||
{
|
||||
auto& members = *object.m_data.m_value.object;
|
||||
auto it = members.lower_bound(key);
|
||||
if (it != members.end() && !members.key_comp()(key, it->first))
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const auto old_capacity = object.container_capacity();
|
||||
it = members.emplace_hint(it, key, nullptr);
|
||||
return object.set_parent_after_insert(it->second, old_capacity);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static BasicJsonType& object_member_impl(BasicJsonType& object, const string_t& key, detail::priority_tag<0> /*unused*/)
|
||||
{
|
||||
auto& members = *object.m_data.m_value.object;
|
||||
const auto it = members.find(key);
|
||||
@@ -22844,6 +22863,12 @@ class json_pointer
|
||||
return object.operator[](key);
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
static BasicJsonType& object_member(BasicJsonType& object, const string_t& key)
|
||||
{
|
||||
return object_member_impl(object, key, detail::priority_tag<1> {});
|
||||
}
|
||||
|
||||
JSON_PRIVATE_UNLESS_TESTED:
|
||||
json_pointer top() const
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user