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