1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
8 // http://opensource.org/licenses/MIT
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
19 #include "rapidjson/rapidjson.h"
20 #include "rapidjson/document.h"
21 #include "rapidjson/prettywriter.h"
22 #include "rapidjson/stringbuffer.h"
23 #include "rapidjson/filereadstream.h"
24 #include "rapidjson/encodedstream.h"
25 #include "rapidjson/memorystream.h"
28 #define SIMD_SUFFIX(name) name##_SSE2
29 #elif defined(RAPIDJSON_SSE42)
30 #define SIMD_SUFFIX(name) name##_SSE42
32 #define SIMD_SUFFIX(name) name
35 using namespace rapidjson
;
37 class RapidJson
: public PerfTest
{
39 RapidJson() : temp_(), doc_() {}
41 virtual void SetUp() {
44 // temp buffer for insitu parsing.
45 temp_
= (char *)malloc(length_
+ 1);
47 // Parse as a document
48 EXPECT_FALSE(doc_
.Parse(json_
).HasParseError());
50 for (size_t i
= 0; i
< 7; i
++)
51 EXPECT_FALSE(typesDoc_
[i
].Parse(types_
[i
]).HasParseError());
54 virtual void TearDown() {
60 RapidJson(const RapidJson
&);
61 RapidJson
& operator=(const RapidJson
&);
66 Document typesDoc_
[7];
69 TEST_F(RapidJson
, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler
)) {
70 for (size_t i
= 0; i
< kTrialCount
; i
++) {
71 memcpy(temp_
, json_
, length_
+ 1);
72 InsituStringStream
s(temp_
);
73 BaseReaderHandler
<> h
;
75 EXPECT_TRUE(reader
.Parse
<kParseInsituFlag
>(s
, h
));
79 TEST_F(RapidJson
, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler_ValidateEncoding
)) {
80 for (size_t i
= 0; i
< kTrialCount
; i
++) {
81 memcpy(temp_
, json_
, length_
+ 1);
82 InsituStringStream
s(temp_
);
83 BaseReaderHandler
<> h
;
85 EXPECT_TRUE(reader
.Parse
<kParseInsituFlag
| kParseValidateEncodingFlag
>(s
, h
));
89 TEST_F(RapidJson
, SIMD_SUFFIX(ReaderParse_DummyHandler
)) {
90 for (size_t i
= 0; i
< kTrialCount
; i
++) {
91 StringStream
s(json_
);
92 BaseReaderHandler
<> h
;
94 EXPECT_TRUE(reader
.Parse(s
, h
));
98 #define TEST_TYPED(index, Name)\
99 TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_##Name)) {\
100 for (size_t i = 0; i < kTrialCount * 10; i++) {\
101 StringStream s(types_[index]);\
102 BaseReaderHandler<> h;\
104 EXPECT_TRUE(reader.Parse(s, h));\
107 TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler_##Name)) {\
108 for (size_t i = 0; i < kTrialCount * 10; i++) {\
109 memcpy(temp_, types_[index], typesLength_[index] + 1);\
110 InsituStringStream s(temp_);\
111 BaseReaderHandler<> h;\
113 EXPECT_TRUE(reader.Parse<kParseInsituFlag>(s, h));\
117 TEST_TYPED(0, Booleans
)
118 TEST_TYPED(1, Floats
)
120 TEST_TYPED(3, Integers
)
123 TEST_TYPED(6, Paragraphs
)
127 TEST_F(RapidJson
, SIMD_SUFFIX(ReaderParse_DummyHandler_FullPrecision
)) {
128 for (size_t i
= 0; i
< kTrialCount
; i
++) {
129 StringStream
s(json_
);
130 BaseReaderHandler
<> h
;
132 EXPECT_TRUE(reader
.Parse
<kParseFullPrecisionFlag
>(s
, h
));
136 TEST_F(RapidJson
, SIMD_SUFFIX(ReaderParseIterative_DummyHandler
)) {
137 for (size_t i
= 0; i
< kTrialCount
; i
++) {
138 StringStream
s(json_
);
139 BaseReaderHandler
<> h
;
141 EXPECT_TRUE(reader
.Parse
<kParseIterativeFlag
>(s
, h
));
145 TEST_F(RapidJson
, SIMD_SUFFIX(ReaderParseIterativeInsitu_DummyHandler
)) {
146 for (size_t i
= 0; i
< kTrialCount
; i
++) {
147 memcpy(temp_
, json_
, length_
+ 1);
148 InsituStringStream
s(temp_
);
149 BaseReaderHandler
<> h
;
151 EXPECT_TRUE(reader
.Parse
<kParseIterativeFlag
|kParseInsituFlag
>(s
, h
));
155 TEST_F(RapidJson
, SIMD_SUFFIX(ReaderParse_DummyHandler_ValidateEncoding
)) {
156 for (size_t i
= 0; i
< kTrialCount
; i
++) {
157 StringStream
s(json_
);
158 BaseReaderHandler
<> h
;
160 EXPECT_TRUE(reader
.Parse
<kParseValidateEncodingFlag
>(s
, h
));
164 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParseInsitu_MemoryPoolAllocator
)) {
165 for (size_t i
= 0; i
< kTrialCount
; i
++) {
166 memcpy(temp_
, json_
, length_
+ 1);
168 doc
.ParseInsitu(temp_
);
169 ASSERT_TRUE(doc
.IsObject());
173 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParseIterativeInsitu_MemoryPoolAllocator
)) {
174 for (size_t i
= 0; i
< kTrialCount
; i
++) {
175 memcpy(temp_
, json_
, length_
+ 1);
177 doc
.ParseInsitu
<kParseIterativeFlag
>(temp_
);
178 ASSERT_TRUE(doc
.IsObject());
182 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParse_MemoryPoolAllocator
)) {
183 for (size_t i
= 0; i
< kTrialCount
; i
++) {
186 ASSERT_TRUE(doc
.IsObject());
190 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParseLength_MemoryPoolAllocator
)) {
191 for (size_t i
= 0; i
< kTrialCount
; i
++) {
193 doc
.Parse(json_
, length_
);
194 ASSERT_TRUE(doc
.IsObject());
198 #if RAPIDJSON_HAS_STDSTRING
199 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParseStdString_MemoryPoolAllocator
)) {
200 const std::string
s(json_
, length_
);
201 for (size_t i
= 0; i
< kTrialCount
; i
++) {
204 ASSERT_TRUE(doc
.IsObject());
209 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParseIterative_MemoryPoolAllocator
)) {
210 for (size_t i
= 0; i
< kTrialCount
; i
++) {
212 doc
.Parse
<kParseIterativeFlag
>(json_
);
213 ASSERT_TRUE(doc
.IsObject());
217 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParse_CrtAllocator
)) {
218 for (size_t i
= 0; i
< kTrialCount
; i
++) {
219 memcpy(temp_
, json_
, length_
+ 1);
220 GenericDocument
<UTF8
<>, CrtAllocator
> doc
;
222 ASSERT_TRUE(doc
.IsObject());
226 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParseEncodedInputStream_MemoryStream
)) {
227 for (size_t i
= 0; i
< kTrialCount
; i
++) {
228 MemoryStream
ms(json_
, length_
);
229 EncodedInputStream
<UTF8
<>, MemoryStream
> is(ms
);
231 doc
.ParseStream
<0, UTF8
<> >(is
);
232 ASSERT_TRUE(doc
.IsObject());
236 TEST_F(RapidJson
, SIMD_SUFFIX(DocumentParseAutoUTFInputStream_MemoryStream
)) {
237 for (size_t i
= 0; i
< kTrialCount
; i
++) {
238 MemoryStream
ms(json_
, length_
);
239 AutoUTFInputStream
<unsigned, MemoryStream
> is(ms
);
241 doc
.ParseStream
<0, AutoUTF
<unsigned> >(is
);
242 ASSERT_TRUE(doc
.IsObject());
247 size_t Traverse(const T
& value
) {
249 switch(value
.GetType()) {
251 for (typename
T::ConstMemberIterator itr
= value
.MemberBegin(); itr
!= value
.MemberEnd(); ++itr
) {
253 count
+= Traverse(itr
->value
);
258 for (typename
T::ConstValueIterator itr
= value
.Begin(); itr
!= value
.End(); ++itr
)
259 count
+= Traverse(*itr
);
269 TEST_F(RapidJson
, DocumentTraverse
) {
270 for (size_t i
= 0; i
< kTrialCount
; i
++) {
271 size_t count
= Traverse(doc_
);
272 EXPECT_EQ(4339u, count
);
274 // std::cout << count << std::endl;
280 RAPIDJSON_DIAG_OFF(effc
++)
283 struct ValueCounter
: public BaseReaderHandler
<> {
284 ValueCounter() : count_(1) {} // root
286 bool EndObject(SizeType memberCount
) { count_
+= memberCount
* 2; return true; }
287 bool EndArray(SizeType elementCount
) { count_
+= elementCount
; return true; }
296 TEST_F(RapidJson
, DocumentAccept
) {
297 for (size_t i
= 0; i
< kTrialCount
; i
++) {
298 ValueCounter counter
;
299 doc_
.Accept(counter
);
300 EXPECT_EQ(4339u, counter
.count_
);
307 NullStream() /*: length_(0)*/ {}
308 void Put(Ch
) { /*++length_;*/ }
313 TEST_F(RapidJson
, Writer_NullStream
) {
314 for (size_t i
= 0; i
< kTrialCount
; i
++) {
316 Writer
<NullStream
> writer(s
);
319 // std::cout << s.length_ << std::endl;
323 TEST_F(RapidJson
, SIMD_SUFFIX(Writer_StringBuffer
)) {
324 for (size_t i
= 0; i
< kTrialCount
; i
++) {
325 StringBuffer
s(0, 1024 * 1024);
326 Writer
<StringBuffer
> writer(s
);
328 const char* str
= s
.GetString();
331 // std::cout << strlen(str) << std::endl;
335 #define TEST_TYPED(index, Name)\
336 TEST_F(RapidJson, SIMD_SUFFIX(Writer_StringBuffer_##Name)) {\
337 for (size_t i = 0; i < kTrialCount * 10; i++) {\
338 StringBuffer s(0, 1024 * 1024);\
339 Writer<StringBuffer> writer(s);\
340 typesDoc_[index].Accept(writer);\
341 const char* str = s.GetString();\
346 TEST_TYPED(0, Booleans
)
347 TEST_TYPED(1, Floats
)
349 TEST_TYPED(3, Integers
)
352 TEST_TYPED(6, Paragraphs
)
356 TEST_F(RapidJson
, SIMD_SUFFIX(PrettyWriter_StringBuffer
)) {
357 for (size_t i
= 0; i
< kTrialCount
; i
++) {
358 StringBuffer
s(0, 2048 * 1024);
359 PrettyWriter
<StringBuffer
> writer(s
);
360 writer
.SetIndent(' ', 1);
362 const char* str
= s
.GetString();
365 // std::cout << strlen(str) << std::endl;
369 TEST_F(RapidJson
, internal_Pow10
) {
371 for (size_t i
= 0; i
< kTrialCount
* kTrialCount
; i
++)
372 sum
+= internal::Pow10(int(i
& 255));
376 TEST_F(RapidJson
, SkipWhitespace_Basic
) {
377 for (size_t i
= 0; i
< kTrialCount
; i
++) {
378 rapidjson::StringStream
s(whitespace_
);
379 while (s
.Peek() == ' ' || s
.Peek() == '\n' || s
.Peek() == '\r' || s
.Peek() == '\t')
381 ASSERT_EQ('[', s
.Peek());
385 TEST_F(RapidJson
, SIMD_SUFFIX(SkipWhitespace
)) {
386 for (size_t i
= 0; i
< kTrialCount
; i
++) {
387 rapidjson::StringStream
s(whitespace_
);
388 rapidjson::SkipWhitespace(s
);
389 ASSERT_EQ('[', s
.Peek());
393 TEST_F(RapidJson
, SkipWhitespace_strspn
) {
394 for (size_t i
= 0; i
< kTrialCount
; i
++) {
395 const char* s
= whitespace_
+ std::strspn(whitespace_
, " \t\r\n");
400 TEST_F(RapidJson
, UTF8_Validate
) {
403 for (size_t i
= 0; i
< kTrialCount
; i
++) {
404 StringStream
is(json_
);
406 while (is
.Peek() != '\0')
407 result
&= UTF8
<>::Validate(is
, os
);
412 TEST_F(RapidJson
, FileReadStream
) {
413 for (size_t i
= 0; i
< kTrialCount
; i
++) {
414 FILE *fp
= fopen(filename_
, "rb");
416 FileReadStream
s(fp
, buffer
, sizeof(buffer
));
417 while (s
.Take() != '\0')
423 TEST_F(RapidJson
, SIMD_SUFFIX(ReaderParse_DummyHandler_FileReadStream
)) {
424 for (size_t i
= 0; i
< kTrialCount
; i
++) {
425 FILE *fp
= fopen(filename_
, "rb");
427 FileReadStream
s(fp
, buffer
, sizeof(buffer
));
428 BaseReaderHandler
<> h
;
435 TEST_F(RapidJson
, StringBuffer
) {
437 for (int i
= 0; i
< 32 * 1024 * 1024; i
++)
441 #endif // TEST_RAPIDJSON