Electroneum
Loading...
Searching...
No Matches
rapidjsontest.cpp
Go to the documentation of this file.
1// Tencent is pleased to support the open source community by making RapidJSON available.
2//
3// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4//
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
7//
8// http://opensource.org/licenses/MIT
9//
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.
14
15#include "perftest.h"
16
17#if TEST_RAPIDJSON
18
19#include "rapidjson/rapidjson.h"
20#include "rapidjson/document.h"
26
27#ifdef RAPIDJSON_SSE2
28#define SIMD_SUFFIX(name) name##_SSE2
29#elif defined(RAPIDJSON_SSE42)
30#define SIMD_SUFFIX(name) name##_SSE42
31#elif defined(RAPIDJSON_NEON)
32#define SIMD_SUFFIX(name) name##_NEON
33#else
34#define SIMD_SUFFIX(name) name
35#endif
36
37using namespace rapidjson;
38
39class RapidJson : public PerfTest {
40public:
41 RapidJson() : temp_(), doc_() {}
42
43 virtual void SetUp() {
44 PerfTest::SetUp();
45
46 // temp buffer for insitu parsing.
47 temp_ = (char *)malloc(length_ + 1);
48
49 // Parse as a document
50 EXPECT_FALSE(doc_.Parse(json_).HasParseError());
51
52 for (size_t i = 0; i < 7; i++)
53 EXPECT_FALSE(typesDoc_[i].Parse(types_[i]).HasParseError());
54 }
55
56 virtual void TearDown() {
57 PerfTest::TearDown();
58 free(temp_);
59 }
60
61private:
62 RapidJson(const RapidJson&);
64
65protected:
66 char *temp_;
69};
70
71TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler)) {
72 for (size_t i = 0; i < kTrialCount; i++) {
73 memcpy(temp_, json_, length_ + 1);
74 InsituStringStream s(temp_);
76 Reader reader;
77 EXPECT_TRUE(reader.Parse<kParseInsituFlag>(s, h));
78 }
79}
80
81TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler_ValidateEncoding)) {
82 for (size_t i = 0; i < kTrialCount; i++) {
83 memcpy(temp_, json_, length_ + 1);
84 InsituStringStream s(temp_);
86 Reader reader;
88 }
89}
90
91TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler)) {
92 for (size_t i = 0; i < kTrialCount; i++) {
93 StringStream s(json_);
95 Reader reader;
96 EXPECT_TRUE(reader.Parse(s, h));
97 }
98}
99
100#define TEST_TYPED(index, Name)\
101TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_##Name)) {\
102 for (size_t i = 0; i < kTrialCount * 10; i++) {\
103 StringStream s(types_[index]);\
104 BaseReaderHandler<> h;\
105 Reader reader;\
106 EXPECT_TRUE(reader.Parse(s, h));\
107 }\
108}\
109TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler_##Name)) {\
110 for (size_t i = 0; i < kTrialCount * 10; i++) {\
111 memcpy(temp_, types_[index], typesLength_[index] + 1);\
112 InsituStringStream s(temp_);\
113 BaseReaderHandler<> h;\
114 Reader reader;\
115 EXPECT_TRUE(reader.Parse<kParseInsituFlag>(s, h));\
116 }\
117}
118
119TEST_TYPED(0, Booleans)
120TEST_TYPED(1, Floats)
121TEST_TYPED(2, Guids)
122TEST_TYPED(3, Integers)
123TEST_TYPED(4, Mixed)
124TEST_TYPED(5, Nulls)
125TEST_TYPED(6, Paragraphs)
126
127#undef TEST_TYPED
128
129TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FullPrecision)) {
130 for (size_t i = 0; i < kTrialCount; i++) {
131 StringStream s(json_);
133 Reader reader;
135 }
136}
137
138TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterative_DummyHandler)) {
139 for (size_t i = 0; i < kTrialCount; i++) {
140 StringStream s(json_);
142 Reader reader;
144 }
145}
146
147TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterativeInsitu_DummyHandler)) {
148 for (size_t i = 0; i < kTrialCount; i++) {
149 memcpy(temp_, json_, length_ + 1);
150 InsituStringStream s(temp_);
152 Reader reader;
154 }
155}
156
157TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterativePull_DummyHandler)) {
158 for (size_t i = 0; i < kTrialCount; i++) {
159 StringStream s(json_);
161 Reader reader;
162 reader.IterativeParseInit();
163 while (!reader.IterativeParseComplete()) {
164 if (!reader.IterativeParseNext<kParseDefaultFlags>(s, h))
165 break;
166 }
167 EXPECT_FALSE(reader.HasParseError());
168 }
169}
170
171TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterativePullInsitu_DummyHandler)) {
172 for (size_t i = 0; i < kTrialCount; i++) {
173 memcpy(temp_, json_, length_ + 1);
174 InsituStringStream s(temp_);
176 Reader reader;
177 reader.IterativeParseInit();
178 while (!reader.IterativeParseComplete()) {
180 break;
181 }
182 EXPECT_FALSE(reader.HasParseError());
183 }
184}
185
186TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_ValidateEncoding)) {
187 for (size_t i = 0; i < kTrialCount; i++) {
188 StringStream s(json_);
190 Reader reader;
192 }
193}
194
195TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseInsitu_MemoryPoolAllocator)) {
196 for (size_t i = 0; i < kTrialCount; i++) {
197 memcpy(temp_, json_, length_ + 1);
198 Document doc;
199 doc.ParseInsitu(temp_);
200 ASSERT_TRUE(doc.IsObject());
201 }
202}
203
204TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseIterativeInsitu_MemoryPoolAllocator)) {
205 for (size_t i = 0; i < kTrialCount; i++) {
206 memcpy(temp_, json_, length_ + 1);
207 Document doc;
209 ASSERT_TRUE(doc.IsObject());
210 }
211}
212
213TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_MemoryPoolAllocator)) {
214 for (size_t i = 0; i < kTrialCount; i++) {
215 Document doc;
216 doc.Parse(json_);
217 ASSERT_TRUE(doc.IsObject());
218 }
219}
220
221TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseLength_MemoryPoolAllocator)) {
222 for (size_t i = 0; i < kTrialCount; i++) {
223 Document doc;
224 doc.Parse(json_, length_);
225 ASSERT_TRUE(doc.IsObject());
226 }
227}
228
229#if RAPIDJSON_HAS_STDSTRING
230TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseStdString_MemoryPoolAllocator)) {
231 const std::string s(json_, length_);
232 for (size_t i = 0; i < kTrialCount; i++) {
233 Document doc;
234 doc.Parse(s);
235 ASSERT_TRUE(doc.IsObject());
236 }
237}
238#endif
239
240TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseIterative_MemoryPoolAllocator)) {
241 for (size_t i = 0; i < kTrialCount; i++) {
242 Document doc;
243 doc.Parse<kParseIterativeFlag>(json_);
244 ASSERT_TRUE(doc.IsObject());
245 }
246}
247
248TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_CrtAllocator)) {
249 for (size_t i = 0; i < kTrialCount; i++) {
250 memcpy(temp_, json_, length_ + 1);
252 doc.Parse(temp_);
253 ASSERT_TRUE(doc.IsObject());
254 }
255}
256
257TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseEncodedInputStream_MemoryStream)) {
258 for (size_t i = 0; i < kTrialCount; i++) {
259 MemoryStream ms(json_, length_);
261 Document doc;
262 doc.ParseStream<0, UTF8<> >(is);
263 ASSERT_TRUE(doc.IsObject());
264 }
265}
266
267TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseAutoUTFInputStream_MemoryStream)) {
268 for (size_t i = 0; i < kTrialCount; i++) {
269 MemoryStream ms(json_, length_);
271 Document doc;
272 doc.ParseStream<0, AutoUTF<unsigned> >(is);
273 ASSERT_TRUE(doc.IsObject());
274 }
275}
276
277template<typename T>
278size_t Traverse(const T& value) {
279 size_t count = 1;
280 switch(value.GetType()) {
281 case kObjectType:
282 for (typename T::ConstMemberIterator itr = value.MemberBegin(); itr != value.MemberEnd(); ++itr) {
283 count++; // name
284 count += Traverse(itr->value);
285 }
286 break;
287
288 case kArrayType:
289 for (typename T::ConstValueIterator itr = value.Begin(); itr != value.End(); ++itr)
290 count += Traverse(*itr);
291 break;
292
293 default:
294 // Do nothing.
295 break;
296 }
297 return count;
298}
299
300TEST_F(RapidJson, DocumentTraverse) {
301 for (size_t i = 0; i < kTrialCount; i++) {
302 size_t count = Traverse(doc_);
303 EXPECT_EQ(4339u, count);
304 //if (i == 0)
305 // std::cout << count << std::endl;
306 }
307}
308
309#ifdef __GNUC__
310RAPIDJSON_DIAG_PUSH
311RAPIDJSON_DIAG_OFF(effc++)
312#endif
313
315 ValueCounter() : count_(1) {} // root
316
317 bool EndObject(SizeType memberCount) { count_ += memberCount * 2; return true; }
318 bool EndArray(SizeType elementCount) { count_ += elementCount; return true; }
319
321};
322
323#ifdef __GNUC__
324RAPIDJSON_DIAG_POP
325#endif
326
327TEST_F(RapidJson, DocumentAccept) {
328 for (size_t i = 0; i < kTrialCount; i++) {
329 ValueCounter counter;
330 doc_.Accept(counter);
331 EXPECT_EQ(4339u, counter.count_);
332 }
333}
334
336 typedef char Ch;
337
338 NullStream() /*: length_(0)*/ {}
339 void Put(Ch) { /*++length_;*/ }
340 void Flush() {}
341 //size_t length_;
342};
343
344TEST_F(RapidJson, Writer_NullStream) {
345 for (size_t i = 0; i < kTrialCount; i++) {
346 NullStream s;
347 Writer<NullStream> writer(s);
348 doc_.Accept(writer);
349 //if (i == 0)
350 // std::cout << s.length_ << std::endl;
351 }
352}
353
354TEST_F(RapidJson, SIMD_SUFFIX(Writer_StringBuffer)) {
355 for (size_t i = 0; i < kTrialCount; i++) {
356 StringBuffer s(0, 1024 * 1024);
357 Writer<StringBuffer> writer(s);
358 doc_.Accept(writer);
359 const char* str = s.GetString();
360 (void)str;
361 //if (i == 0)
362 // std::cout << strlen(str) << std::endl;
363 }
364}
365
366#define TEST_TYPED(index, Name)\
367TEST_F(RapidJson, SIMD_SUFFIX(Writer_StringBuffer_##Name)) {\
368 for (size_t i = 0; i < kTrialCount * 10; i++) {\
369 StringBuffer s(0, 1024 * 1024);\
370 Writer<StringBuffer> writer(s);\
371 typesDoc_[index].Accept(writer);\
372 const char* str = s.GetString();\
373 (void)str;\
374 }\
375}
376
377TEST_TYPED(0, Booleans)
378TEST_TYPED(1, Floats)
379TEST_TYPED(2, Guids)
380TEST_TYPED(3, Integers)
381TEST_TYPED(4, Mixed)
382TEST_TYPED(5, Nulls)
383TEST_TYPED(6, Paragraphs)
384
385#undef TEST_TYPED
386
387TEST_F(RapidJson, SIMD_SUFFIX(PrettyWriter_StringBuffer)) {
388 for (size_t i = 0; i < kTrialCount; i++) {
389 StringBuffer s(0, 2048 * 1024);
391 writer.SetIndent(' ', 1);
392 doc_.Accept(writer);
393 const char* str = s.GetString();
394 (void)str;
395 //if (i == 0)
396 // std::cout << strlen(str) << std::endl;
397 }
398}
399
400TEST_F(RapidJson, internal_Pow10) {
401 double sum = 0;
402 for (size_t i = 0; i < kTrialCount * kTrialCount; i++)
403 sum += internal::Pow10(int(i & 255));
404 EXPECT_GT(sum, 0.0);
405}
406
407TEST_F(RapidJson, SkipWhitespace_Basic) {
408 for (size_t i = 0; i < kTrialCount; i++) {
409 rapidjson::StringStream s(whitespace_);
410 while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
411 s.Take();
412 ASSERT_EQ('[', s.Peek());
413 }
414}
415
417 for (size_t i = 0; i < kTrialCount; i++) {
418 rapidjson::StringStream s(whitespace_);
419 rapidjson::SkipWhitespace(s);
420 ASSERT_EQ('[', s.Peek());
421 }
422}
423
424TEST_F(RapidJson, SkipWhitespace_strspn) {
425 for (size_t i = 0; i < kTrialCount; i++) {
426 const char* s = whitespace_ + std::strspn(whitespace_, " \t\r\n");
427 ASSERT_EQ('[', *s);
428 }
429}
430
431TEST_F(RapidJson, UTF8_Validate) {
432 NullStream os;
433
434 for (size_t i = 0; i < kTrialCount; i++) {
435 StringStream is(json_);
436 bool result = true;
437 while (is.Peek() != '\0')
438 result &= UTF8<>::Validate(is, os);
439 EXPECT_TRUE(result);
440 }
441}
442
444 for (size_t i = 0; i < kTrialCount; i++) {
445 FILE *fp = fopen(filename_, "rb");
446 char buffer[65536];
447 FileReadStream s(fp, buffer, sizeof(buffer));
448 while (s.Take() != '\0')
449 ;
450 fclose(fp);
451 }
452}
453
454TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FileReadStream)) {
455 for (size_t i = 0; i < kTrialCount; i++) {
456 FILE *fp = fopen(filename_, "rb");
457 char buffer[65536];
458 FileReadStream s(fp, buffer, sizeof(buffer));
460 Reader reader;
461 reader.Parse(s, h);
462 fclose(fp);
463 }
464}
465
467 StringBuffer sb;
468 for (int i = 0; i < 32 * 1024 * 1024; i++)
469 sb.Put(i & 0x7f);
470}
471
472#endif // TEST_RAPIDJSON
connection< TProtocol > & operator=(const connection< TProtocol > &obj)
Input stream wrapper with dynamically bound encoding and automatic encoding detection.
C-runtime library allocator.
Definition allocators.h:75
Input byte stream wrapper with a statically bound encoding.
File byte stream for input using fread().
A document for parsing JSON text as DOM.
Definition document.h:2130
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition document.h:2308
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion).
Definition document.h:2265
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion).
Definition document.h:2331
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition reader.h:557
bool IterativeParseNext(InputStream &is, Handler &handler)
Parse one token from JSON text.
Definition reader.h:618
void IterativeParseInit()
Initialize JSON text token-by-token parsing.
Definition reader.h:605
RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const
Check if token-by-token parsing JSON text is complete.
Definition reader.h:675
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition reader.h:680
const Ch * GetString() const
Writer with indentation and spacing.
PrettyWriter & SetIndent(Ch indentChar, unsigned indentCharCount)
Set custom indentation.
Document doc_
virtual void TearDown()
virtual void SetUp()
Document typesDoc_[7]
JSON writer.
Definition writer.h:89
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition document.h:2512
GenericStringStream< UTF8< char > > StringStream
Definition fwd.h:49
GenericInsituStringStream< UTF8< char > > InsituStringStream
Definition fwd.h:54
GenericReader< UTF8< char >, UTF8< char >, CrtAllocator > Reader
Definition fwd.h:90
GenericStringBuffer< UTF8< char >, CrtAllocator > StringBuffer
Definition fwd.h:61
#define TEST_F(test_fixture, test_name)
Definition gtest.h:2216
#define ASSERT_EQ(val1, val2)
Definition gtest.h:1956
#define EXPECT_EQ(val1, val2)
Definition gtest.h:1922
#define EXPECT_GT(val1, val2)
Definition gtest.h:1934
#define EXPECT_TRUE(condition)
Definition gtest.h:1859
#define ASSERT_TRUE(condition)
Definition gtest.h:1865
#define EXPECT_FALSE(condition)
Definition gtest.h:1862
void * memcpy(void *a, const void *b, size_t c)
double Pow10(int n)
Computes integer powers of 10 in double (10.0^n).
Definition pow10.h:28
main RapidJSON namespace
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
common definitions and configuration
@ kObjectType
object
Definition rapidjson.h:624
@ kArrayType
array
Definition rapidjson.h:625
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition rapidjson.h:389
#define SIMD_SUFFIX(name)
#define TEST_TYPED(index, Name)
size_t Traverse(const T &value)
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition reader.h:264
@ kParseFullPrecisionFlag
Parse number in full precision (but slower).
Definition reader.h:151
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition reader.h:147
@ kParseDefaultFlags
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS.
Definition reader.h:156
@ kParseValidateEncodingFlag
Validate encoding of JSON strings.
Definition reader.h:148
@ kParseIterativeFlag
Iterative(constant complexity in terms of function call stack size) parsing.
Definition reader.h:149
Dynamically select encoding according to stream's runtime-specified UTF encoding type.
Definition encodings.h:615
Default implementation of Handler.
Definition reader.h:196
Ch Peek() const
Definition stream.h:159
Represents an in-memory input byte stream.
UTF-8 encoding.
Definition encodings.h:96
static bool Validate(InputStream &is, OutputStream &os)
Definition encodings.h:179
bool EndArray(SizeType elementCount)
bool EndObject(SizeType memberCount)
#define T(x)