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