rapidjsontest.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  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. #include "perftest.h"
  15. #if TEST_RAPIDJSON
  16. #include "rapidjson/rapidjson.h"
  17. #include "rapidjson/document.h"
  18. #include "rapidjson/prettywriter.h"
  19. #include "rapidjson/stringbuffer.h"
  20. #include "rapidjson/filereadstream.h"
  21. #include "rapidjson/encodedstream.h"
  22. #include "rapidjson/memorystream.h"
  23. #ifdef RAPIDJSON_SSE2
  24. #define SIMD_SUFFIX(name) name##_SSE2
  25. #elif defined(RAPIDJSON_SSE42)
  26. #define SIMD_SUFFIX(name) name##_SSE42
  27. #else
  28. #define SIMD_SUFFIX(name) name
  29. #endif
  30. using namespace rapidjson;
  31. class RapidJson : public PerfTest {
  32. public:
  33. RapidJson() : temp_(), doc_() {}
  34. virtual void SetUp() {
  35. PerfTest::SetUp();
  36. // temp buffer for insitu parsing.
  37. temp_ = (char *)malloc(length_ + 1);
  38. // Parse as a document
  39. EXPECT_FALSE(doc_.Parse(json_).HasParseError());
  40. for (size_t i = 0; i < 7; i++)
  41. EXPECT_FALSE(typesDoc_[i].Parse(types_[i]).HasParseError());
  42. }
  43. virtual void TearDown() {
  44. PerfTest::TearDown();
  45. free(temp_);
  46. }
  47. private:
  48. RapidJson(const RapidJson&);
  49. RapidJson& operator=(const RapidJson&);
  50. protected:
  51. char *temp_;
  52. Document doc_;
  53. Document typesDoc_[7];
  54. };
  55. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler)) {
  56. for (size_t i = 0; i < kTrialCount; i++) {
  57. memcpy(temp_, json_, length_ + 1);
  58. InsituStringStream s(temp_);
  59. BaseReaderHandler<> h;
  60. Reader reader;
  61. EXPECT_TRUE(reader.Parse<kParseInsituFlag>(s, h));
  62. }
  63. }
  64. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler_ValidateEncoding)) {
  65. for (size_t i = 0; i < kTrialCount; i++) {
  66. memcpy(temp_, json_, length_ + 1);
  67. InsituStringStream s(temp_);
  68. BaseReaderHandler<> h;
  69. Reader reader;
  70. EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseValidateEncodingFlag>(s, h));
  71. }
  72. }
  73. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler)) {
  74. for (size_t i = 0; i < kTrialCount; i++) {
  75. StringStream s(json_);
  76. BaseReaderHandler<> h;
  77. Reader reader;
  78. EXPECT_TRUE(reader.Parse(s, h));
  79. }
  80. }
  81. #define TEST_TYPED(index, Name)\
  82. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_##Name)) {\
  83. for (size_t i = 0; i < kTrialCount * 10; i++) {\
  84. StringStream s(types_[index]);\
  85. BaseReaderHandler<> h;\
  86. Reader reader;\
  87. EXPECT_TRUE(reader.Parse(s, h));\
  88. }\
  89. }\
  90. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler_##Name)) {\
  91. for (size_t i = 0; i < kTrialCount * 10; i++) {\
  92. memcpy(temp_, types_[index], typesLength_[index] + 1);\
  93. InsituStringStream s(temp_);\
  94. BaseReaderHandler<> h;\
  95. Reader reader;\
  96. EXPECT_TRUE(reader.Parse<kParseInsituFlag>(s, h));\
  97. }\
  98. }
  99. TEST_TYPED(0, Booleans)
  100. TEST_TYPED(1, Floats)
  101. TEST_TYPED(2, Guids)
  102. TEST_TYPED(3, Integers)
  103. TEST_TYPED(4, Mixed)
  104. TEST_TYPED(5, Nulls)
  105. TEST_TYPED(6, Paragraphs)
  106. #undef TEST_TYPED
  107. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FullPrecision)) {
  108. for (size_t i = 0; i < kTrialCount; i++) {
  109. StringStream s(json_);
  110. BaseReaderHandler<> h;
  111. Reader reader;
  112. EXPECT_TRUE(reader.Parse<kParseFullPrecisionFlag>(s, h));
  113. }
  114. }
  115. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterative_DummyHandler)) {
  116. for (size_t i = 0; i < kTrialCount; i++) {
  117. StringStream s(json_);
  118. BaseReaderHandler<> h;
  119. Reader reader;
  120. EXPECT_TRUE(reader.Parse<kParseIterativeFlag>(s, h));
  121. }
  122. }
  123. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterativeInsitu_DummyHandler)) {
  124. for (size_t i = 0; i < kTrialCount; i++) {
  125. memcpy(temp_, json_, length_ + 1);
  126. InsituStringStream s(temp_);
  127. BaseReaderHandler<> h;
  128. Reader reader;
  129. EXPECT_TRUE(reader.Parse<kParseIterativeFlag|kParseInsituFlag>(s, h));
  130. }
  131. }
  132. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_ValidateEncoding)) {
  133. for (size_t i = 0; i < kTrialCount; i++) {
  134. StringStream s(json_);
  135. BaseReaderHandler<> h;
  136. Reader reader;
  137. EXPECT_TRUE(reader.Parse<kParseValidateEncodingFlag>(s, h));
  138. }
  139. }
  140. TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseInsitu_MemoryPoolAllocator)) {
  141. for (size_t i = 0; i < kTrialCount; i++) {
  142. memcpy(temp_, json_, length_ + 1);
  143. Document doc;
  144. doc.ParseInsitu(temp_);
  145. ASSERT_TRUE(doc.IsObject());
  146. }
  147. }
  148. TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseIterativeInsitu_MemoryPoolAllocator)) {
  149. for (size_t i = 0; i < kTrialCount; i++) {
  150. memcpy(temp_, json_, length_ + 1);
  151. Document doc;
  152. doc.ParseInsitu<kParseIterativeFlag>(temp_);
  153. ASSERT_TRUE(doc.IsObject());
  154. }
  155. }
  156. TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_MemoryPoolAllocator)) {
  157. for (size_t i = 0; i < kTrialCount; i++) {
  158. Document doc;
  159. doc.Parse(json_);
  160. ASSERT_TRUE(doc.IsObject());
  161. }
  162. }
  163. TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseIterative_MemoryPoolAllocator)) {
  164. for (size_t i = 0; i < kTrialCount; i++) {
  165. Document doc;
  166. doc.Parse<kParseIterativeFlag>(json_);
  167. ASSERT_TRUE(doc.IsObject());
  168. }
  169. }
  170. TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_CrtAllocator)) {
  171. for (size_t i = 0; i < kTrialCount; i++) {
  172. memcpy(temp_, json_, length_ + 1);
  173. GenericDocument<UTF8<>, CrtAllocator> doc;
  174. doc.Parse(temp_);
  175. ASSERT_TRUE(doc.IsObject());
  176. }
  177. }
  178. TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseEncodedInputStream_MemoryStream)) {
  179. for (size_t i = 0; i < kTrialCount; i++) {
  180. MemoryStream ms(json_, length_);
  181. EncodedInputStream<UTF8<>, MemoryStream> is(ms);
  182. Document doc;
  183. doc.ParseStream<0, UTF8<> >(is);
  184. ASSERT_TRUE(doc.IsObject());
  185. }
  186. }
  187. TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseAutoUTFInputStream_MemoryStream)) {
  188. for (size_t i = 0; i < kTrialCount; i++) {
  189. MemoryStream ms(json_, length_);
  190. AutoUTFInputStream<unsigned, MemoryStream> is(ms);
  191. Document doc;
  192. doc.ParseStream<0, AutoUTF<unsigned> >(is);
  193. ASSERT_TRUE(doc.IsObject());
  194. }
  195. }
  196. template<typename T>
  197. size_t Traverse(const T& value) {
  198. size_t count = 1;
  199. switch(value.GetType()) {
  200. case kObjectType:
  201. for (typename T::ConstMemberIterator itr = value.MemberBegin(); itr != value.MemberEnd(); ++itr) {
  202. count++; // name
  203. count += Traverse(itr->value);
  204. }
  205. break;
  206. case kArrayType:
  207. for (typename T::ConstValueIterator itr = value.Begin(); itr != value.End(); ++itr)
  208. count += Traverse(*itr);
  209. break;
  210. default:
  211. // Do nothing.
  212. break;
  213. }
  214. return count;
  215. }
  216. TEST_F(RapidJson, DocumentTraverse) {
  217. for (size_t i = 0; i < kTrialCount; i++) {
  218. size_t count = Traverse(doc_);
  219. EXPECT_EQ(4339u, count);
  220. //if (i == 0)
  221. // std::cout << count << std::endl;
  222. }
  223. }
  224. #ifdef __GNUC__
  225. RAPIDJSON_DIAG_PUSH
  226. RAPIDJSON_DIAG_OFF(effc++)
  227. #endif
  228. struct ValueCounter : public BaseReaderHandler<> {
  229. ValueCounter() : count_(1) {} // root
  230. bool EndObject(SizeType memberCount) { count_ += memberCount * 2; return true; }
  231. bool EndArray(SizeType elementCount) { count_ += elementCount; return true; }
  232. SizeType count_;
  233. };
  234. #ifdef __GNUC__
  235. RAPIDJSON_DIAG_POP
  236. #endif
  237. TEST_F(RapidJson, DocumentAccept) {
  238. for (size_t i = 0; i < kTrialCount; i++) {
  239. ValueCounter counter;
  240. doc_.Accept(counter);
  241. EXPECT_EQ(4339u, counter.count_);
  242. }
  243. }
  244. struct NullStream {
  245. typedef char Ch;
  246. NullStream() /*: length_(0)*/ {}
  247. void Put(Ch) { /*++length_;*/ }
  248. void Flush() {}
  249. //size_t length_;
  250. };
  251. TEST_F(RapidJson, Writer_NullStream) {
  252. for (size_t i = 0; i < kTrialCount; i++) {
  253. NullStream s;
  254. Writer<NullStream> writer(s);
  255. doc_.Accept(writer);
  256. //if (i == 0)
  257. // std::cout << s.length_ << std::endl;
  258. }
  259. }
  260. TEST_F(RapidJson, Writer_StringBuffer) {
  261. for (size_t i = 0; i < kTrialCount; i++) {
  262. StringBuffer s(0, 1024 * 1024);
  263. Writer<StringBuffer> writer(s);
  264. doc_.Accept(writer);
  265. const char* str = s.GetString();
  266. (void)str;
  267. //if (i == 0)
  268. // std::cout << strlen(str) << std::endl;
  269. }
  270. }
  271. #define TEST_TYPED(index, Name)\
  272. TEST_F(RapidJson, Writer_StringBuffer_##Name) {\
  273. for (size_t i = 0; i < kTrialCount * 10; i++) {\
  274. StringBuffer s(0, 1024 * 1024);\
  275. Writer<StringBuffer> writer(s);\
  276. typesDoc_[index].Accept(writer);\
  277. const char* str = s.GetString();\
  278. (void)str;\
  279. }\
  280. }
  281. TEST_TYPED(0, Booleans)
  282. TEST_TYPED(1, Floats)
  283. TEST_TYPED(2, Guids)
  284. TEST_TYPED(3, Integers)
  285. TEST_TYPED(4, Mixed)
  286. TEST_TYPED(5, Nulls)
  287. TEST_TYPED(6, Paragraphs)
  288. #undef TEST_TYPED
  289. TEST_F(RapidJson, PrettyWriter_StringBuffer) {
  290. for (size_t i = 0; i < kTrialCount; i++) {
  291. StringBuffer s(0, 2048 * 1024);
  292. PrettyWriter<StringBuffer> writer(s);
  293. writer.SetIndent(' ', 1);
  294. doc_.Accept(writer);
  295. const char* str = s.GetString();
  296. (void)str;
  297. //if (i == 0)
  298. // std::cout << strlen(str) << std::endl;
  299. }
  300. }
  301. TEST_F(RapidJson, internal_Pow10) {
  302. double sum = 0;
  303. for (size_t i = 0; i < kTrialCount * kTrialCount; i++)
  304. sum += internal::Pow10(int(i & 255));
  305. EXPECT_GT(sum, 0.0);
  306. }
  307. TEST_F(RapidJson, SkipWhitespace_Basic) {
  308. for (size_t i = 0; i < kTrialCount; i++) {
  309. rapidjson::StringStream s(whitespace_);
  310. while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
  311. s.Take();
  312. ASSERT_EQ('[', s.Peek());
  313. }
  314. }
  315. TEST_F(RapidJson, SIMD_SUFFIX(SkipWhitespace)) {
  316. for (size_t i = 0; i < kTrialCount; i++) {
  317. rapidjson::StringStream s(whitespace_);
  318. rapidjson::SkipWhitespace(s);
  319. ASSERT_EQ('[', s.Peek());
  320. }
  321. }
  322. TEST_F(RapidJson, SkipWhitespace_strspn) {
  323. for (size_t i = 0; i < kTrialCount; i++) {
  324. const char* s = whitespace_ + std::strspn(whitespace_, " \t\r\n");
  325. ASSERT_EQ('[', *s);
  326. }
  327. }
  328. TEST_F(RapidJson, UTF8_Validate) {
  329. NullStream os;
  330. for (size_t i = 0; i < kTrialCount; i++) {
  331. StringStream is(json_);
  332. bool result = true;
  333. while (is.Peek() != '\0')
  334. result &= UTF8<>::Validate(is, os);
  335. EXPECT_TRUE(result);
  336. }
  337. }
  338. TEST_F(RapidJson, FileReadStream) {
  339. for (size_t i = 0; i < kTrialCount; i++) {
  340. FILE *fp = fopen(filename_, "rb");
  341. char buffer[65536];
  342. FileReadStream s(fp, buffer, sizeof(buffer));
  343. while (s.Take() != '\0')
  344. ;
  345. fclose(fp);
  346. }
  347. }
  348. TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FileReadStream)) {
  349. for (size_t i = 0; i < kTrialCount; i++) {
  350. FILE *fp = fopen(filename_, "rb");
  351. char buffer[65536];
  352. FileReadStream s(fp, buffer, sizeof(buffer));
  353. BaseReaderHandler<> h;
  354. Reader reader;
  355. reader.Parse(s, h);
  356. fclose(fp);
  357. }
  358. }
  359. TEST_F(RapidJson, StringBuffer) {
  360. StringBuffer sb;
  361. for (int i = 0; i < 32 * 1024 * 1024; i++)
  362. sb.Put(i & 0x7f);
  363. }
  364. #endif // TEST_RAPIDJSON