mirror of
https://github.com/nlohmann/json.git
synced 2026-10-22 22:08:55 +00:00
Write the scalar elements of a container without entering dump_internal()
Every element of an array or object went through dump_internal(), whose frame holds the state for descending into a container (callee-saved registers, indentation, depth). A scalar, which is what most elements are, needs none of it, and paid for the entry and exit regardless. The loops now call dump_scalar() directly for anything that is not an object or an array, and dump_internal() for those only. Apple M1, Apple clang, retired instructions per dump(), on top of the previous change: small object 2997 -> 2712 (-10 %) signed_ints 276M -> 252M (-9 %) floats 323M -> 301M (-7 %) jeopardy 501M -> 462M (-8 %) citm_catalog 5.96M -> 5.61M (-6 %) twitter 4.40M -> 4.12M (-6 %) canada 39.2M -> 37.0M (-5 %) Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
2 files changed
+58
-16
No files matched your search
@@ -178,7 +178,7 @@ class serializer
|
||||
{
|
||||
put_indent(new_indent);
|
||||
put_quoted(i->first, "\": ");
|
||||
dump_internal(i->second, new_indent, depth + 1);
|
||||
dump_element(i->second, new_indent, depth + 1);
|
||||
put_literal(",\n");
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ class serializer
|
||||
JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
|
||||
put_indent(new_indent);
|
||||
put_quoted(i->first, "\": ");
|
||||
dump_internal(i->second, new_indent, depth + 1);
|
||||
dump_element(i->second, new_indent, depth + 1);
|
||||
|
||||
put_char('\n');
|
||||
put_indent(current_indent);
|
||||
@@ -202,7 +202,7 @@ class serializer
|
||||
for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
|
||||
{
|
||||
put_quoted(i->first, "\":");
|
||||
dump_internal(i->second, current_indent, depth + 1);
|
||||
dump_element(i->second, current_indent, depth + 1);
|
||||
put_char(',');
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ class serializer
|
||||
JSON_ASSERT(i != val.m_data.m_value.object->cend());
|
||||
JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
|
||||
put_quoted(i->first, "\":");
|
||||
dump_internal(i->second, current_indent, depth + 1);
|
||||
dump_element(i->second, current_indent, depth + 1);
|
||||
|
||||
put_char('}');
|
||||
}
|
||||
@@ -244,14 +244,14 @@ class serializer
|
||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||
{
|
||||
put_indent(new_indent);
|
||||
dump_internal(*i, new_indent, depth + 1);
|
||||
dump_element(*i, new_indent, depth + 1);
|
||||
put_literal(",\n");
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(!val.m_data.m_value.array->empty());
|
||||
put_indent(new_indent);
|
||||
dump_internal(val.m_data.m_value.array->back(), new_indent, depth + 1);
|
||||
dump_element(val.m_data.m_value.array->back(), new_indent, depth + 1);
|
||||
|
||||
put_char('\n');
|
||||
put_indent(current_indent);
|
||||
@@ -265,13 +265,13 @@ class serializer
|
||||
for (auto i = val.m_data.m_value.array->cbegin();
|
||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||
{
|
||||
dump_internal(*i, current_indent, depth + 1);
|
||||
dump_element(*i, current_indent, depth + 1);
|
||||
put_char(',');
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(!val.m_data.m_value.array->empty());
|
||||
dump_internal(val.m_data.m_value.array->back(), current_indent, depth + 1);
|
||||
dump_element(val.m_data.m_value.array->back(), current_indent, depth + 1);
|
||||
|
||||
put_char(']');
|
||||
}
|
||||
@@ -294,6 +294,27 @@ class serializer
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
@brief serialize an element of a container
|
||||
|
||||
Most elements are scalars, which need none of the state dump_internal() keeps
|
||||
for a container; writing them from here spares each the entry and exit of
|
||||
that function.
|
||||
*/
|
||||
JSON_HEDLEY_ALWAYS_INLINE void dump_element(const BasicJsonType& val,
|
||||
const std::size_t current_indent,
|
||||
const std::size_t depth)
|
||||
{
|
||||
if (val.m_data.m_type == value_t::object || val.m_data.m_type == value_t::array)
|
||||
{
|
||||
dump_internal(val, current_indent, depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
dump_scalar(val, current_indent);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief write out @a val and everything below it without the call stack
|
||||
|
||||
|
||||
Generated
+29
-8
@@ -30322,7 +30322,7 @@ class serializer
|
||||
{
|
||||
put_indent(new_indent);
|
||||
put_quoted(i->first, "\": ");
|
||||
dump_internal(i->second, new_indent, depth + 1);
|
||||
dump_element(i->second, new_indent, depth + 1);
|
||||
put_literal(",\n");
|
||||
}
|
||||
|
||||
@@ -30331,7 +30331,7 @@ class serializer
|
||||
JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
|
||||
put_indent(new_indent);
|
||||
put_quoted(i->first, "\": ");
|
||||
dump_internal(i->second, new_indent, depth + 1);
|
||||
dump_element(i->second, new_indent, depth + 1);
|
||||
|
||||
put_char('\n');
|
||||
put_indent(current_indent);
|
||||
@@ -30346,7 +30346,7 @@ class serializer
|
||||
for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
|
||||
{
|
||||
put_quoted(i->first, "\":");
|
||||
dump_internal(i->second, current_indent, depth + 1);
|
||||
dump_element(i->second, current_indent, depth + 1);
|
||||
put_char(',');
|
||||
}
|
||||
|
||||
@@ -30354,7 +30354,7 @@ class serializer
|
||||
JSON_ASSERT(i != val.m_data.m_value.object->cend());
|
||||
JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
|
||||
put_quoted(i->first, "\":");
|
||||
dump_internal(i->second, current_indent, depth + 1);
|
||||
dump_element(i->second, current_indent, depth + 1);
|
||||
|
||||
put_char('}');
|
||||
}
|
||||
@@ -30388,14 +30388,14 @@ class serializer
|
||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||
{
|
||||
put_indent(new_indent);
|
||||
dump_internal(*i, new_indent, depth + 1);
|
||||
dump_element(*i, new_indent, depth + 1);
|
||||
put_literal(",\n");
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(!val.m_data.m_value.array->empty());
|
||||
put_indent(new_indent);
|
||||
dump_internal(val.m_data.m_value.array->back(), new_indent, depth + 1);
|
||||
dump_element(val.m_data.m_value.array->back(), new_indent, depth + 1);
|
||||
|
||||
put_char('\n');
|
||||
put_indent(current_indent);
|
||||
@@ -30409,13 +30409,13 @@ class serializer
|
||||
for (auto i = val.m_data.m_value.array->cbegin();
|
||||
i != val.m_data.m_value.array->cend() - 1; ++i)
|
||||
{
|
||||
dump_internal(*i, current_indent, depth + 1);
|
||||
dump_element(*i, current_indent, depth + 1);
|
||||
put_char(',');
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(!val.m_data.m_value.array->empty());
|
||||
dump_internal(val.m_data.m_value.array->back(), current_indent, depth + 1);
|
||||
dump_element(val.m_data.m_value.array->back(), current_indent, depth + 1);
|
||||
|
||||
put_char(']');
|
||||
}
|
||||
@@ -30438,6 +30438,27 @@ class serializer
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
@brief serialize an element of a container
|
||||
|
||||
Most elements are scalars, which need none of the state dump_internal() keeps
|
||||
for a container; writing them from here spares each the entry and exit of
|
||||
that function.
|
||||
*/
|
||||
JSON_HEDLEY_ALWAYS_INLINE void dump_element(const BasicJsonType& val,
|
||||
const std::size_t current_indent,
|
||||
const std::size_t depth)
|
||||
{
|
||||
if (val.m_data.m_type == value_t::object || val.m_data.m_type == value_t::array)
|
||||
{
|
||||
dump_internal(val, current_indent, depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
dump_scalar(val, current_indent);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief write out @a val and everything below it without the call stack
|
||||
|
||||
|
||||
Reference in new issue
Block a user