⚡ micro-optimizations for dump()
Added separate code paths for normal output and pritty-printed output. This allowed to remove most of the ifs along the way. Benchmarks and cachegrind suggest a 10% performance improvement.
This commit is contained in:
parent
ae155c4734
commit
bd0326cbc1
2 changed files with 108 additions and 84 deletions
92
src/json.hpp
92
src/json.hpp
|
@ -8414,9 +8414,6 @@ class basic_json
|
||||||
const unsigned int indent_step,
|
const unsigned int indent_step,
|
||||||
const unsigned int current_indent = 0) const
|
const unsigned int current_indent = 0) const
|
||||||
{
|
{
|
||||||
// variable to hold indentation for recursive calls
|
|
||||||
unsigned int new_indent = current_indent;
|
|
||||||
|
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
case value_t::object:
|
case value_t::object:
|
||||||
|
@ -8427,35 +8424,43 @@ class basic_json
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
o << "{";
|
|
||||||
|
|
||||||
// increase indentation
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
new_indent += indent_step;
|
o << "{\n";
|
||||||
o << "\n";
|
|
||||||
}
|
// variable to hold indentation for recursive calls
|
||||||
|
const auto new_indent = current_indent + indent_step;
|
||||||
|
const std::string indent_string = string_t(new_indent, ' ');
|
||||||
|
|
||||||
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
|
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
|
||||||
{
|
{
|
||||||
if (i != m_value.object->cbegin())
|
if (i != m_value.object->cbegin())
|
||||||
{
|
{
|
||||||
o << (pretty_print ? ",\n" : ",");
|
o << ",\n";
|
||||||
}
|
}
|
||||||
o << string_t(new_indent, ' ') << "\""
|
o << indent_string << '\"' << escape_string(i->first) << "\": ";
|
||||||
<< escape_string(i->first) << "\":"
|
i->second.dump(o, true, indent_step, new_indent);
|
||||||
<< (pretty_print ? " " : "");
|
|
||||||
i->second.dump(o, pretty_print, indent_step, new_indent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrease indentation
|
o << '\n' << string_t(current_indent, ' ') + '}';
|
||||||
if (pretty_print)
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
new_indent -= indent_step;
|
o << '{';
|
||||||
o << "\n";
|
|
||||||
|
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
|
||||||
|
{
|
||||||
|
if (i != m_value.object->cbegin())
|
||||||
|
{
|
||||||
|
o << ',';
|
||||||
|
}
|
||||||
|
o << '\"' << escape_string(i->first) << "\":";
|
||||||
|
i->second.dump(o, false, indent_step, current_indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
o << '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
o << string_t(new_indent, ' ') + "}";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8467,39 +8472,46 @@ class basic_json
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
o << "[";
|
|
||||||
|
|
||||||
// increase indentation
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
new_indent += indent_step;
|
o << "[\n";
|
||||||
o << "\n";
|
|
||||||
|
// variable to hold indentation for recursive calls
|
||||||
|
const auto new_indent = current_indent + indent_step;
|
||||||
|
const std::string indent_string = string_t(new_indent, ' ');
|
||||||
|
|
||||||
|
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
||||||
|
{
|
||||||
|
o << indent_string;
|
||||||
|
i->dump(o, true, indent_step, new_indent);
|
||||||
|
o << ",\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
|
o << indent_string;
|
||||||
{
|
assert(not m_value.array->empty());
|
||||||
if (i != m_value.array->cbegin())
|
m_value.array->back().dump(o, true, indent_step, new_indent);
|
||||||
{
|
|
||||||
o << (pretty_print ? ",\n" : ",");
|
o << '\n' << string_t(current_indent, ' ') << ']';
|
||||||
}
|
}
|
||||||
o << string_t(new_indent, ' ');
|
else
|
||||||
i->dump(o, pretty_print, indent_step, new_indent);
|
{
|
||||||
|
o << '[';
|
||||||
|
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
||||||
|
{
|
||||||
|
i->dump(o, false, indent_step, current_indent);
|
||||||
|
o << ',';
|
||||||
|
}
|
||||||
|
assert(not m_value.array->empty());
|
||||||
|
m_value.array->back().dump(o, false, indent_step, current_indent);
|
||||||
|
o << ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrease indentation
|
|
||||||
if (pretty_print)
|
|
||||||
{
|
|
||||||
new_indent -= indent_step;
|
|
||||||
o << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
o << string_t(new_indent, ' ') << "]";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
{
|
{
|
||||||
o << string_t("\"") << escape_string(*m_value.string) << "\"";
|
o << '\"' << escape_string(*m_value.string) << '\"';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8414,9 +8414,6 @@ class basic_json
|
||||||
const unsigned int indent_step,
|
const unsigned int indent_step,
|
||||||
const unsigned int current_indent = 0) const
|
const unsigned int current_indent = 0) const
|
||||||
{
|
{
|
||||||
// variable to hold indentation for recursive calls
|
|
||||||
unsigned int new_indent = current_indent;
|
|
||||||
|
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
case value_t::object:
|
case value_t::object:
|
||||||
|
@ -8427,35 +8424,43 @@ class basic_json
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
o << "{";
|
|
||||||
|
|
||||||
// increase indentation
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
new_indent += indent_step;
|
o << "{\n";
|
||||||
o << "\n";
|
|
||||||
}
|
// variable to hold indentation for recursive calls
|
||||||
|
const auto new_indent = current_indent + indent_step;
|
||||||
|
const std::string indent_string = string_t(new_indent, ' ');
|
||||||
|
|
||||||
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
|
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
|
||||||
{
|
{
|
||||||
if (i != m_value.object->cbegin())
|
if (i != m_value.object->cbegin())
|
||||||
{
|
{
|
||||||
o << (pretty_print ? ",\n" : ",");
|
o << ",\n";
|
||||||
}
|
}
|
||||||
o << string_t(new_indent, ' ') << "\""
|
o << indent_string << '\"' << escape_string(i->first) << "\": ";
|
||||||
<< escape_string(i->first) << "\":"
|
i->second.dump(o, true, indent_step, new_indent);
|
||||||
<< (pretty_print ? " " : "");
|
|
||||||
i->second.dump(o, pretty_print, indent_step, new_indent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrease indentation
|
o << '\n' << string_t(current_indent, ' ') + '}';
|
||||||
if (pretty_print)
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
new_indent -= indent_step;
|
o << '{';
|
||||||
o << "\n";
|
|
||||||
|
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
|
||||||
|
{
|
||||||
|
if (i != m_value.object->cbegin())
|
||||||
|
{
|
||||||
|
o << ',';
|
||||||
|
}
|
||||||
|
o << '\"' << escape_string(i->first) << "\":";
|
||||||
|
i->second.dump(o, false, indent_step, current_indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
o << '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
o << string_t(new_indent, ' ') + "}";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8467,39 +8472,46 @@ class basic_json
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
o << "[";
|
|
||||||
|
|
||||||
// increase indentation
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
new_indent += indent_step;
|
o << "[\n";
|
||||||
o << "\n";
|
|
||||||
|
// variable to hold indentation for recursive calls
|
||||||
|
const auto new_indent = current_indent + indent_step;
|
||||||
|
const std::string indent_string = string_t(new_indent, ' ');
|
||||||
|
|
||||||
|
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
||||||
|
{
|
||||||
|
o << indent_string;
|
||||||
|
i->dump(o, true, indent_step, new_indent);
|
||||||
|
o << ",\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
|
o << indent_string;
|
||||||
{
|
assert(not m_value.array->empty());
|
||||||
if (i != m_value.array->cbegin())
|
m_value.array->back().dump(o, true, indent_step, new_indent);
|
||||||
{
|
|
||||||
o << (pretty_print ? ",\n" : ",");
|
o << '\n' << string_t(current_indent, ' ') << ']';
|
||||||
}
|
}
|
||||||
o << string_t(new_indent, ' ');
|
else
|
||||||
i->dump(o, pretty_print, indent_step, new_indent);
|
{
|
||||||
|
o << '[';
|
||||||
|
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
||||||
|
{
|
||||||
|
i->dump(o, false, indent_step, current_indent);
|
||||||
|
o << ',';
|
||||||
|
}
|
||||||
|
assert(not m_value.array->empty());
|
||||||
|
m_value.array->back().dump(o, false, indent_step, current_indent);
|
||||||
|
o << ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrease indentation
|
|
||||||
if (pretty_print)
|
|
||||||
{
|
|
||||||
new_indent -= indent_step;
|
|
||||||
o << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
o << string_t(new_indent, ' ') << "]";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
{
|
{
|
||||||
o << string_t("\"") << escape_string(*m_value.string) << "\"";
|
o << '\"' << escape_string(*m_value.string) << '\"';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue