From 2aab79207e5165190c360a0bc30eecae9e08306e Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Wed, 26 Nov 2014 23:11:00 +0100 Subject: [PATCH] GenericValue: improve copying performance The GenericValue "copy" constructor (with Allocator) uses a temporary GenericDocument object to perform the deep copying with the provided allocator. This leads to the temporary allocation of the `Stack` memory, even in case of shallow values (numbers, etc.). This patch improves the performance of this operation by only resorting the the SAX Handler implementation in case of Array or Object values. --- include/rapidjson/document.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 047bc66..56e2f2e 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -1896,9 +1896,26 @@ template inline GenericValue::GenericValue(const GenericValue& rhs, Allocator& allocator) { - GenericDocument d(&allocator); - rhs.Accept(d); - RawAssign(*d.stack_.template Pop(1)); + switch (rhs.GetType()) { + case kObjectType: + case kArrayType: { // perform deep copy via SAX Handler + GenericDocument d(&allocator); + rhs.Accept(d); + RawAssign(*d.stack_.template Pop(1)); + } + break; + case kStringType: + if (rhs.flags_ == kConstStringFlag) { + flags_ = rhs.flags_; + data_ = *reinterpret_cast(&rhs.data_); + } else { + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + } + break; + default: // kNumberType, kTrueType, kFalseType, kNullType + flags_ = rhs.flags_; + data_ = *reinterpret_cast(&rhs.data_); + } } RAPIDJSON_NAMESPACE_END