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.
parent ae155c47
...@@ -8414,9 +8414,6 @@ class basic_json ...@@ -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 ...@@ -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
{
o << '{';
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
{ {
new_indent -= indent_step; if (i != m_value.object->cbegin())
o << "\n"; {
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 ...@@ -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";
}
for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i) // variable to hold indentation for recursive calls
{ const auto new_indent = current_indent + indent_step;
if (i != m_value.array->cbegin()) const std::string indent_string = string_t(new_indent, ' ');
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
{ {
o << (pretty_print ? ",\n" : ","); o << indent_string;
} i->dump(o, true, indent_step, new_indent);
o << string_t(new_indent, ' '); o << ",\n";
i->dump(o, pretty_print, indent_step, new_indent);
} }
// decrease indentation o << indent_string;
if (pretty_print) assert(not m_value.array->empty());
m_value.array->back().dump(o, true, indent_step, new_indent);
o << '\n' << string_t(current_indent, ' ') << ']';
}
else
{
o << '[';
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
{ {
new_indent -= indent_step; i->dump(o, false, indent_step, current_indent);
o << "\n"; o << ',';
}
assert(not m_value.array->empty());
m_value.array->back().dump(o, false, indent_step, current_indent);
o << ']';
} }
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 ...@@ -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 ...@@ -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
{
o << '{';
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
{ {
new_indent -= indent_step; if (i != m_value.object->cbegin())
o << "\n"; {
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 ...@@ -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";
}
for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i) // variable to hold indentation for recursive calls
{ const auto new_indent = current_indent + indent_step;
if (i != m_value.array->cbegin()) const std::string indent_string = string_t(new_indent, ' ');
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
{ {
o << (pretty_print ? ",\n" : ","); o << indent_string;
} i->dump(o, true, indent_step, new_indent);
o << string_t(new_indent, ' '); o << ",\n";
i->dump(o, pretty_print, indent_step, new_indent);
} }
// decrease indentation o << indent_string;
if (pretty_print) assert(not m_value.array->empty());
m_value.array->back().dump(o, true, indent_step, new_indent);
o << '\n' << string_t(current_indent, ' ') << ']';
}
else
{
o << '[';
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
{ {
new_indent -= indent_step; i->dump(o, false, indent_step, current_indent);
o << "\n"; o << ',';
}
assert(not m_value.array->empty());
m_value.array->back().dump(o, false, indent_step, current_indent);
o << ']';
} }
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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment