⚡ micro-optimizations for dump()
All ‘<<‘ calls have been replaced by write()/put() calls. The indentation strings needs not to be resized. Cachegrind measures 1% performance improvement.
This commit is contained in:
parent
b1441f3485
commit
0f04e42dd5
2 changed files with 132 additions and 52 deletions
92
src/json.hpp
92
src/json.hpp
|
@ -8420,47 +8420,69 @@ class basic_json
|
||||||
{
|
{
|
||||||
if (m_value.object->empty())
|
if (m_value.object->empty())
|
||||||
{
|
{
|
||||||
o << "{}";
|
o.write("{}", 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
o << "{\n";
|
o.write("{\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + indent_step;
|
||||||
string_t indent_string = string_t(new_indent, ' ');
|
string_t indent_string = string_t(new_indent, ' ');
|
||||||
|
|
||||||
|
// first n-1 elements
|
||||||
auto i = m_value.object->cbegin();
|
auto i = m_value.object->cbegin();
|
||||||
for (size_t cnt = 0; cnt < m_value.object->size() - 1; ++cnt, ++i)
|
for (size_t cnt = 0; cnt < m_value.object->size() - 1; ++cnt, ++i)
|
||||||
{
|
{
|
||||||
o << indent_string << '\"' << escape_string(i->first) << "\": ";
|
o.write(indent_string.c_str(), new_indent);
|
||||||
|
o.put('\"');
|
||||||
|
const auto s = escape_string(i->first);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.write("\": ", 3);
|
||||||
i->second.dump(o, true, indent_step, new_indent);
|
i->second.dump(o, true, indent_step, new_indent);
|
||||||
o << ",\n";
|
o.write(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
o << indent_string << '\"' << escape_string(i->first) << "\": ";
|
// last element
|
||||||
|
assert(i != m_value.object->cend());
|
||||||
|
o.write(indent_string.c_str(), new_indent);
|
||||||
|
o.put('\"');
|
||||||
|
const auto s = escape_string(i->first);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.write("\": ", 3);
|
||||||
i->second.dump(o, true, indent_step, new_indent);
|
i->second.dump(o, true, indent_step, new_indent);
|
||||||
|
|
||||||
indent_string.resize(current_indent);
|
o.put('\n');
|
||||||
o << '\n' << indent_string << '}';
|
o.write(indent_string.c_str(), current_indent);
|
||||||
|
o.put('}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o << '{';
|
o.put('{');
|
||||||
|
|
||||||
|
// first n-1 elements
|
||||||
auto i = m_value.object->cbegin();
|
auto i = m_value.object->cbegin();
|
||||||
for (size_t cnt = 0; cnt < m_value.object->size() - 1; ++cnt, ++i)
|
for (size_t cnt = 0; cnt < m_value.object->size() - 1; ++cnt, ++i)
|
||||||
{
|
{
|
||||||
o << '\"' << escape_string(i->first) << "\":";
|
o.put('\"');
|
||||||
|
const auto s = escape_string(i->first);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.write("\":", 2);
|
||||||
i->second.dump(o, false, indent_step, current_indent);
|
i->second.dump(o, false, indent_step, current_indent);
|
||||||
o << ',';
|
o.put(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
o << '\"' << escape_string(i->first) << "\":";
|
// last element
|
||||||
|
assert(i != m_value.object->cend());
|
||||||
|
o.put('\"');
|
||||||
|
const auto s = escape_string(i->first);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.write("\":", 2);
|
||||||
i->second.dump(o, false, indent_step, current_indent);
|
i->second.dump(o, false, indent_step, current_indent);
|
||||||
o << '}';
|
|
||||||
|
o.put('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -8470,43 +8492,51 @@ class basic_json
|
||||||
{
|
{
|
||||||
if (m_value.array->empty())
|
if (m_value.array->empty())
|
||||||
{
|
{
|
||||||
o << "[]";
|
o.write("[]", 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
o << "[\n";
|
o.write("[\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + indent_step;
|
||||||
string_t indent_string = string_t(new_indent, ' ');
|
string_t indent_string = string_t(new_indent, ' ');
|
||||||
|
|
||||||
|
// first n-1 elements
|
||||||
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
o << indent_string;
|
o.write(indent_string.c_str(), new_indent);
|
||||||
i->dump(o, true, indent_step, new_indent);
|
i->dump(o, true, indent_step, new_indent);
|
||||||
o << ",\n";
|
o.write(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
o << indent_string;
|
// last element
|
||||||
assert(not m_value.array->empty());
|
assert(not m_value.array->empty());
|
||||||
|
o.write(indent_string.c_str(), new_indent);
|
||||||
m_value.array->back().dump(o, true, indent_step, new_indent);
|
m_value.array->back().dump(o, true, indent_step, new_indent);
|
||||||
|
|
||||||
indent_string.resize(current_indent);
|
o.put('\n');
|
||||||
o << '\n' << indent_string << ']';
|
o.write(indent_string.c_str(), current_indent);
|
||||||
|
o.put(']');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o << '[';
|
o.put('[');
|
||||||
|
|
||||||
|
// first n-1 elements
|
||||||
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
i->dump(o, false, indent_step, current_indent);
|
i->dump(o, false, indent_step, current_indent);
|
||||||
o << ',';
|
o.put(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// last element
|
||||||
assert(not m_value.array->empty());
|
assert(not m_value.array->empty());
|
||||||
m_value.array->back().dump(o, false, indent_step, current_indent);
|
m_value.array->back().dump(o, false, indent_step, current_indent);
|
||||||
o << ']';
|
|
||||||
|
o.put(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -8514,13 +8544,23 @@ class basic_json
|
||||||
|
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
{
|
{
|
||||||
o << '\"' << escape_string(*m_value.string) << '\"';
|
o.put('\"');
|
||||||
|
const auto s = escape_string(*m_value.string);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.put('\"');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
{
|
{
|
||||||
o << (m_value.boolean ? "true" : "false");
|
if (m_value.boolean)
|
||||||
|
{
|
||||||
|
o.write("true", 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
o.write("false", 5);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8544,13 +8584,13 @@ class basic_json
|
||||||
|
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
{
|
{
|
||||||
o << "<discarded>";
|
o.write("<discarded>", 11);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::null:
|
case value_t::null:
|
||||||
{
|
{
|
||||||
o << "null";
|
o.write("null", 4);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8420,47 +8420,69 @@ class basic_json
|
||||||
{
|
{
|
||||||
if (m_value.object->empty())
|
if (m_value.object->empty())
|
||||||
{
|
{
|
||||||
o << "{}";
|
o.write("{}", 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
o << "{\n";
|
o.write("{\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + indent_step;
|
||||||
string_t indent_string = string_t(new_indent, ' ');
|
string_t indent_string = string_t(new_indent, ' ');
|
||||||
|
|
||||||
|
// first n-1 elements
|
||||||
auto i = m_value.object->cbegin();
|
auto i = m_value.object->cbegin();
|
||||||
for (size_t cnt = 0; cnt < m_value.object->size() - 1; ++cnt, ++i)
|
for (size_t cnt = 0; cnt < m_value.object->size() - 1; ++cnt, ++i)
|
||||||
{
|
{
|
||||||
o << indent_string << '\"' << escape_string(i->first) << "\": ";
|
o.write(indent_string.c_str(), new_indent);
|
||||||
|
o.put('\"');
|
||||||
|
const auto s = escape_string(i->first);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.write("\": ", 3);
|
||||||
i->second.dump(o, true, indent_step, new_indent);
|
i->second.dump(o, true, indent_step, new_indent);
|
||||||
o << ",\n";
|
o.write(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
o << indent_string << '\"' << escape_string(i->first) << "\": ";
|
// last element
|
||||||
|
assert(i != m_value.object->cend());
|
||||||
|
o.write(indent_string.c_str(), new_indent);
|
||||||
|
o.put('\"');
|
||||||
|
const auto s = escape_string(i->first);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.write("\": ", 3);
|
||||||
i->second.dump(o, true, indent_step, new_indent);
|
i->second.dump(o, true, indent_step, new_indent);
|
||||||
|
|
||||||
indent_string.resize(current_indent);
|
o.put('\n');
|
||||||
o << '\n' << indent_string << '}';
|
o.write(indent_string.c_str(), current_indent);
|
||||||
|
o.put('}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o << '{';
|
o.put('{');
|
||||||
|
|
||||||
|
// first n-1 elements
|
||||||
auto i = m_value.object->cbegin();
|
auto i = m_value.object->cbegin();
|
||||||
for (size_t cnt = 0; cnt < m_value.object->size() - 1; ++cnt, ++i)
|
for (size_t cnt = 0; cnt < m_value.object->size() - 1; ++cnt, ++i)
|
||||||
{
|
{
|
||||||
o << '\"' << escape_string(i->first) << "\":";
|
o.put('\"');
|
||||||
|
const auto s = escape_string(i->first);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.write("\":", 2);
|
||||||
i->second.dump(o, false, indent_step, current_indent);
|
i->second.dump(o, false, indent_step, current_indent);
|
||||||
o << ',';
|
o.put(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
o << '\"' << escape_string(i->first) << "\":";
|
// last element
|
||||||
|
assert(i != m_value.object->cend());
|
||||||
|
o.put('\"');
|
||||||
|
const auto s = escape_string(i->first);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.write("\":", 2);
|
||||||
i->second.dump(o, false, indent_step, current_indent);
|
i->second.dump(o, false, indent_step, current_indent);
|
||||||
o << '}';
|
|
||||||
|
o.put('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -8470,43 +8492,51 @@ class basic_json
|
||||||
{
|
{
|
||||||
if (m_value.array->empty())
|
if (m_value.array->empty())
|
||||||
{
|
{
|
||||||
o << "[]";
|
o.write("[]", 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
o << "[\n";
|
o.write("[\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + indent_step;
|
||||||
string_t indent_string = string_t(new_indent, ' ');
|
string_t indent_string = string_t(new_indent, ' ');
|
||||||
|
|
||||||
|
// first n-1 elements
|
||||||
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
o << indent_string;
|
o.write(indent_string.c_str(), new_indent);
|
||||||
i->dump(o, true, indent_step, new_indent);
|
i->dump(o, true, indent_step, new_indent);
|
||||||
o << ",\n";
|
o.write(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
o << indent_string;
|
// last element
|
||||||
assert(not m_value.array->empty());
|
assert(not m_value.array->empty());
|
||||||
|
o.write(indent_string.c_str(), new_indent);
|
||||||
m_value.array->back().dump(o, true, indent_step, new_indent);
|
m_value.array->back().dump(o, true, indent_step, new_indent);
|
||||||
|
|
||||||
indent_string.resize(current_indent);
|
o.put('\n');
|
||||||
o << '\n' << indent_string << ']';
|
o.write(indent_string.c_str(), current_indent);
|
||||||
|
o.put(']');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o << '[';
|
o.put('[');
|
||||||
|
|
||||||
|
// first n-1 elements
|
||||||
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
for (auto i = m_value.array->cbegin(); i != m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
i->dump(o, false, indent_step, current_indent);
|
i->dump(o, false, indent_step, current_indent);
|
||||||
o << ',';
|
o.put(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// last element
|
||||||
assert(not m_value.array->empty());
|
assert(not m_value.array->empty());
|
||||||
m_value.array->back().dump(o, false, indent_step, current_indent);
|
m_value.array->back().dump(o, false, indent_step, current_indent);
|
||||||
o << ']';
|
|
||||||
|
o.put(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -8514,13 +8544,23 @@ class basic_json
|
||||||
|
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
{
|
{
|
||||||
o << '\"' << escape_string(*m_value.string) << '\"';
|
o.put('\"');
|
||||||
|
const auto s = escape_string(*m_value.string);
|
||||||
|
o.write(s.c_str(), static_cast<std::streamsize>(s.size()));
|
||||||
|
o.put('\"');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
{
|
{
|
||||||
o << (m_value.boolean ? "true" : "false");
|
if (m_value.boolean)
|
||||||
|
{
|
||||||
|
o.write("true", 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
o.write("false", 5);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8544,13 +8584,13 @@ class basic_json
|
||||||
|
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
{
|
{
|
||||||
o << "<discarded>";
|
o.write("<discarded>", 11);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::null:
|
case value_t::null:
|
||||||
{
|
{
|
||||||
o << "null";
|
o.write("null", 4);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue