summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2014-09-21 21:52:30 +0000
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2014-09-21 21:52:30 +0000
commitfff1991743c196a471cb5e05569a7631dd15a4fe (patch)
treedea27574ce58e894dea716d81702f3a64fd40271
parent53550424d90c8e4b4e01dbc4d26a4f7235065af6 (diff)
Optimize text_output_indent
We now precompute indent length and have a fast path for lengths 0..4 that avoids calling memcpy in a tight loop. This makes node output 20-30% faster if indentation is enabled. git-svn-id: https://pugixml.googlecode.com/svn/trunk@1018 99668b35-9821-0410-8761-19e4c4f06640
-rw-r--r--src/pugixml.cpp53
1 files changed, 46 insertions, 7 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 767fb48..cc19c10 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -3269,10 +3269,47 @@ PUGI__NS_BEGIN
while (*s);
}
- PUGI__FN void text_output_indent(xml_buffered_writer& writer, const char_t* indent, unsigned int depth)
+ PUGI__FN void text_output_indent(xml_buffered_writer& writer, const char_t* indent, size_t indent_length, unsigned int depth)
{
- for (unsigned int i = 0; i < depth; ++i)
- writer.write(indent);
+ switch (indent_length)
+ {
+ case 0:
+ break;
+
+ case 1:
+ {
+ for (unsigned int i = 0; i < depth; ++i)
+ writer.write(indent[0]);
+ break;
+ }
+
+ case 2:
+ {
+ for (unsigned int i = 0; i < depth; ++i)
+ writer.write(indent[0], indent[1]);
+ break;
+ }
+
+ case 3:
+ {
+ for (unsigned int i = 0; i < depth; ++i)
+ writer.write(indent[0], indent[1], indent[2]);
+ break;
+ }
+
+ case 4:
+ {
+ for (unsigned int i = 0; i < depth; ++i)
+ writer.write(indent[0], indent[1], indent[2], indent[3]);
+ break;
+ }
+
+ default:
+ {
+ for (unsigned int i = 0; i < depth; ++i)
+ writer.write(indent, indent_length);
+ }
+ }
}
PUGI__FN void node_output_attributes(xml_buffered_writer& writer, const xml_node& node, unsigned int flags)
@@ -3413,6 +3450,8 @@ PUGI__NS_BEGIN
PUGI__FN void node_output(xml_buffered_writer& writer, const xml_node& root, const char_t* indent, unsigned int flags, unsigned int depth)
{
+ size_t indent_length = ((flags & (format_indent | format_raw)) == format_indent) ? strlength(indent) : 0;
+
xml_node node = root;
do
@@ -3420,8 +3459,8 @@ PUGI__NS_BEGIN
assert(node);
// begin writing current node
- if ((flags & (format_indent | format_raw)) == format_indent)
- text_output_indent(writer, indent, depth);
+ if (indent_length)
+ text_output_indent(writer, indent, indent_length, depth);
if (node.type() == node_element)
{
@@ -3460,8 +3499,8 @@ PUGI__NS_BEGIN
// write closing node
if (node.type() == node_element)
{
- if ((flags & (format_indent | format_raw)) == format_indent)
- text_output_indent(writer, indent, depth);
+ if (indent_length)
+ text_output_indent(writer, indent, indent_length, depth);
node_output_end(writer, node, flags);
}