From bb6eaa756588df7ed270a4f32a43922f7e006bba Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 22 Sep 2014 06:29:14 +0000 Subject: Optimize and refactor node output implementation a bit (+5% perf gain) git-svn-id: https://pugixml.googlecode.com/svn/trunk@1019 99668b35-9821-0410-8761-19e4c4f06640 --- src/pugixml.cpp | 118 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index cc19c10..28b805d 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -3059,47 +3059,57 @@ PUGI__NS_BEGIN } } - void write(const char_t* data, size_t length) + void write_direct(const char_t* data, size_t length) { - if (bufsize + length > bufcapacity) - { - // flush the remaining buffer contents - flush(); + // flush the remaining buffer contents + flush(); - // handle large chunks - if (length > bufcapacity) + // handle large chunks + if (length > bufcapacity) + { + if (encoding == get_write_native_encoding()) { - if (encoding == get_write_native_encoding()) - { - // fast path, can just write data chunk - writer.write(data, length * sizeof(char_t)); - return; - } - - // need to convert in suitable chunks - while (length > bufcapacity) - { - // get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer - // and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary) - size_t chunk_size = get_valid_length(data, bufcapacity); + // fast path, can just write data chunk + writer.write(data, length * sizeof(char_t)); + return; + } - // convert chunk and write - flush(data, chunk_size); + // need to convert in suitable chunks + while (length > bufcapacity) + { + // get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer + // and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary) + size_t chunk_size = get_valid_length(data, bufcapacity); - // iterate - data += chunk_size; - length -= chunk_size; - } + // convert chunk and write + flush(data, chunk_size); - // small tail is copied below - bufsize = 0; + // iterate + data += chunk_size; + length -= chunk_size; } + + // small tail is copied below + bufsize = 0; } memcpy(buffer + bufsize, data, length * sizeof(char_t)); bufsize += length; } + void write(const char_t* data, size_t length) + { + if (bufsize + length <= bufcapacity) + { + memcpy(buffer + bufsize, data, length * sizeof(char_t)); + bufsize += length; + } + else + { + write_direct(data, length); + } + } + void write(const char_t* data) { write(data, strlength(data)); @@ -3336,7 +3346,8 @@ PUGI__NS_BEGIN writer.write('<'); writer.write(name); - node_output_attributes(writer, node, flags); + if (node.first_attribute()) + node_output_attributes(writer, node, flags); if (flags & format_raw) { @@ -3349,26 +3360,31 @@ PUGI__NS_BEGIN return true; } } - else if (!node.first_child()) - writer.write(' ', '/', '>', '\n'); - else if (node.first_child() == node.last_child() && (node.first_child().type() == node_pcdata || node.first_child().type() == node_cdata)) + else { - writer.write('>'); + xml_node first = node.first_child(); - if (node.first_child().type() == node_pcdata) - text_output(writer, node.first_child().value(), ctx_special_pcdata, flags); - else - text_output_cdata(writer, node.first_child().value()); + if (!first) + writer.write(' ', '/', '>', '\n'); + else if (!first.next_sibling() && (first.type() == node_pcdata || first.type() == node_cdata)) + { + writer.write('>'); - writer.write('<', '/'); - writer.write(name); - writer.write('>', '\n'); - } - else - { - writer.write('>', '\n'); + if (first.type() == node_pcdata) + text_output(writer, first.value(), ctx_special_pcdata, flags); + else + text_output_cdata(writer, first.value()); - return true; + writer.write('<', '/'); + writer.write(name); + writer.write('>', '\n'); + } + else + { + writer.write('>', '\n'); + + return true; + } } return false; @@ -3381,10 +3397,11 @@ PUGI__NS_BEGIN writer.write('<', '/'); writer.write(name); - writer.write('>'); - if ((flags & format_raw) == 0) - writer.write('\n'); + if (flags & format_raw) + writer.write('>'); + else + writer.write('>', '\n'); } PUGI__FN void node_output_simple(xml_buffered_writer& writer, const xml_node& node, unsigned int flags) @@ -4582,10 +4599,7 @@ namespace pugi PUGI__FN xml_node xml_node::next_sibling() const { - if (!_root) return xml_node(); - - if (_root->next_sibling) return xml_node(_root->next_sibling); - else return xml_node(); + return _root ? xml_node(_root->next_sibling) : xml_node(); } PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const -- cgit v1.2.3