rapidjsontest.cpp 10.4 KB
Newer Older
1 2 3
// Tencent is pleased to support the open source community by making RapidJSON available.
// 
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4
//
5 6
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
7
//
8
// http://opensource.org/licenses/MIT
9
//
10 11 12 13
// Unless required by applicable law or agreed to in writing, software distributed 
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
// specific language governing permissions and limitations under the License.
14

15 16 17 18 19 20 21 22
#include "perftest.h"

#if TEST_RAPIDJSON

#include "rapidjson/rapidjson.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
23
#include "rapidjson/filereadstream.h"
24 25
#include "rapidjson/encodedstream.h"
#include "rapidjson/memorystream.h"
26 27 28 29 30 31 32 33 34 35 36 37 38

#ifdef RAPIDJSON_SSE2
#define SIMD_SUFFIX(name) name##_SSE2
#elif defined(RAPIDJSON_SSE42)
#define SIMD_SUFFIX(name) name##_SSE42
#else
#define SIMD_SUFFIX(name) name
#endif

using namespace rapidjson;

class RapidJson : public PerfTest {
public:
39
    RapidJson() : temp_(), doc_() {}
Milo Yip's avatar
Milo Yip committed
40

41 42
    virtual void SetUp() {
        PerfTest::SetUp();
43

44 45
        // temp buffer for insitu parsing.
        temp_ = (char *)malloc(length_ + 1);
46

47 48 49
        // Parse as a document
        EXPECT_FALSE(doc_.Parse(json_).IsNull());
    }
50

51 52 53 54
    virtual void TearDown() {
        PerfTest::TearDown();
        free(temp_);
    }
55

Milo Yip's avatar
Milo Yip committed
56
private:
57 58
    RapidJson(const RapidJson&);
    RapidJson& operator=(const RapidJson&);
Milo Yip's avatar
Milo Yip committed
59

60
protected:
61 62
    char *temp_;
    Document doc_;
63 64
};

65
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler)) {
66 67 68 69 70 71 72
    for (size_t i = 0; i < kTrialCount; i++) {
        memcpy(temp_, json_, length_ + 1);
        InsituStringStream s(temp_);
        BaseReaderHandler<> h;
        Reader reader;
        EXPECT_TRUE(reader.Parse<kParseInsituFlag>(s, h));
    }
73 74
}

75
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler_ValidateEncoding)) {
76 77 78 79 80 81 82
    for (size_t i = 0; i < kTrialCount; i++) {
        memcpy(temp_, json_, length_ + 1);
        InsituStringStream s(temp_);
        BaseReaderHandler<> h;
        Reader reader;
        EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseValidateEncodingFlag>(s, h));
    }
83 84 85
}

TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler)) {
86 87 88 89 90 91
    for (size_t i = 0; i < kTrialCount; i++) {
        StringStream s(json_);
        BaseReaderHandler<> h;
        Reader reader;
        EXPECT_TRUE(reader.Parse(s, h));
    }
92 93
}

miloyip's avatar
miloyip committed
94 95 96 97 98 99 100 101 102
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FullPrecision)) {
    for (size_t i = 0; i < kTrialCount; i++) {
        StringStream s(json_);
        BaseReaderHandler<> h;
        Reader reader;
        EXPECT_TRUE(reader.Parse<kParseFullPrecisionFlag>(s, h));
    }
}

103
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterative_DummyHandler)) {
104 105 106 107 108 109
    for (size_t i = 0; i < kTrialCount; i++) {
        StringStream s(json_);
        BaseReaderHandler<> h;
        Reader reader;
        EXPECT_TRUE(reader.Parse<kParseIterativeFlag>(s, h));
    }
110 111 112
}

TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseIterativeInsitu_DummyHandler)) {
113 114 115 116 117 118 119
    for (size_t i = 0; i < kTrialCount; i++) {
        memcpy(temp_, json_, length_ + 1);
        InsituStringStream s(temp_);
        BaseReaderHandler<> h;
        Reader reader;
        EXPECT_TRUE(reader.Parse<kParseIterativeFlag|kParseInsituFlag>(s, h));
    }
120 121
}

122
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_ValidateEncoding)) {
123 124 125 126 127 128
    for (size_t i = 0; i < kTrialCount; i++) {
        StringStream s(json_);
        BaseReaderHandler<> h;
        Reader reader;
        EXPECT_TRUE(reader.Parse<kParseValidateEncodingFlag>(s, h));
    }
129 130
}

Philipp A. Hartmann's avatar
Philipp A. Hartmann committed
131
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseInsitu_MemoryPoolAllocator)) {
132 133 134 135 136 137
    for (size_t i = 0; i < kTrialCount; i++) {
        memcpy(temp_, json_, length_ + 1);
        Document doc;
        doc.ParseInsitu(temp_);
        ASSERT_TRUE(doc.IsObject());
    }
138
}
139

140
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseIterativeInsitu_MemoryPoolAllocator)) {
141 142 143 144 145 146
    for (size_t i = 0; i < kTrialCount; i++) {
        memcpy(temp_, json_, length_ + 1);
        Document doc;
        doc.ParseInsitu<kParseIterativeFlag>(temp_);
        ASSERT_TRUE(doc.IsObject());
    }
147 148
}

Philipp A. Hartmann's avatar
Philipp A. Hartmann committed
149
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_MemoryPoolAllocator)) {
150 151 152 153 154
    for (size_t i = 0; i < kTrialCount; i++) {
        Document doc;
        doc.Parse(json_);
        ASSERT_TRUE(doc.IsObject());
    }
155
}
156

157
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseIterative_MemoryPoolAllocator)) {
158 159 160 161 162
    for (size_t i = 0; i < kTrialCount; i++) {
        Document doc;
        doc.Parse<kParseIterativeFlag>(json_);
        ASSERT_TRUE(doc.IsObject());
    }
163 164
}

Philipp A. Hartmann's avatar
Philipp A. Hartmann committed
165
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParse_CrtAllocator)) {
166 167 168 169 170 171
    for (size_t i = 0; i < kTrialCount; i++) {
        memcpy(temp_, json_, length_ + 1);
        GenericDocument<UTF8<>, CrtAllocator> doc;
        doc.Parse(temp_);
        ASSERT_TRUE(doc.IsObject());
    }
172 173
}

174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseEncodedInputStream_MemoryStream)) {
    for (size_t i = 0; i < kTrialCount; i++) {
        MemoryStream ms(json_, length_);
        EncodedInputStream<UTF8<>, MemoryStream> is(ms);
        Document doc;
        doc.ParseStream<0, UTF8<> >(is);
        ASSERT_TRUE(doc.IsObject());
    }
}

TEST_F(RapidJson, SIMD_SUFFIX(DocumentParseAutoUTFInputStream_MemoryStream)) {
    for (size_t i = 0; i < kTrialCount; i++) {
        MemoryStream ms(json_, length_);
        AutoUTFInputStream<unsigned, MemoryStream> is(ms);
        Document doc;
        doc.ParseStream<0, AutoUTF<unsigned> >(is);
        ASSERT_TRUE(doc.IsObject());
    }
}

194 195
template<typename T>
size_t Traverse(const T& value) {
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    size_t count = 1;
    switch(value.GetType()) {
        case kObjectType:
            for (typename T::ConstMemberIterator itr = value.MemberBegin(); itr != value.MemberEnd(); ++itr) {
                count++;    // name
                count += Traverse(itr->value);
            }
            break;

        case kArrayType:
            for (typename T::ConstValueIterator itr = value.Begin(); itr != value.End(); ++itr)
                count += Traverse(*itr);
            break;

        default:
            // Do nothing.
            break;
    }
    return count;
215 216 217
}

TEST_F(RapidJson, DocumentTraverse) {
218 219 220 221 222 223
    for (size_t i = 0; i < kTrialCount; i++) {
        size_t count = Traverse(doc_);
        EXPECT_EQ(4339u, count);
        //if (i == 0)
        //  std::cout << count << std::endl;
    }
224 225
}

Milo Yip's avatar
Milo Yip committed
226
#ifdef __GNUC__
227 228
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
Milo Yip's avatar
Milo Yip committed
229 230
#endif

231
struct ValueCounter : public BaseReaderHandler<> {
232
    ValueCounter() : count_(1) {}   // root
233

234 235
    bool EndObject(SizeType memberCount) { count_ += memberCount * 2; return true; }
    bool EndArray(SizeType elementCount) { count_ += elementCount; return true; }
236

237
    SizeType count_;
238 239
};

Milo Yip's avatar
Milo Yip committed
240
#ifdef __GNUC__
241
RAPIDJSON_DIAG_POP
Milo Yip's avatar
Milo Yip committed
242 243
#endif

244
TEST_F(RapidJson, DocumentAccept) {
245 246 247 248 249
    for (size_t i = 0; i < kTrialCount; i++) {
        ValueCounter counter;
        doc_.Accept(counter);
        EXPECT_EQ(4339u, counter.count_);
    }
250 251 252
}

struct NullStream {
253 254 255 256
    NullStream() /*: length_(0)*/ {}
    void Put(char) { /*++length_;*/ }
    void Flush() {}
    //size_t length_;
257 258 259
};

TEST_F(RapidJson, Writer_NullStream) {
260 261 262 263 264 265 266
    for (size_t i = 0; i < kTrialCount; i++) {
        NullStream s;
        Writer<NullStream> writer(s);
        doc_.Accept(writer);
        //if (i == 0)
        //  std::cout << s.length_ << std::endl;
    }
267 268 269
}

TEST_F(RapidJson, Writer_StringBuffer) {
270 271 272 273 274 275 276 277 278
    for (size_t i = 0; i < kTrialCount; i++) {
        StringBuffer s(0, 1024 * 1024);
        Writer<StringBuffer> writer(s);
        doc_.Accept(writer);
        const char* str = s.GetString();
        (void)str;
        //if (i == 0)
        //  std::cout << strlen(str) << std::endl;
    }
279 280 281
}

TEST_F(RapidJson, PrettyWriter_StringBuffer) {
282 283 284 285 286 287 288 289 290 291
    for (size_t i = 0; i < kTrialCount; i++) {
        StringBuffer s(0, 2048 * 1024);
        PrettyWriter<StringBuffer> writer(s);
        writer.SetIndent(' ', 1);
        doc_.Accept(writer);
        const char* str = s.GetString();
        (void)str;
        //if (i == 0)
        //  std::cout << strlen(str) << std::endl;
    }
292 293 294
}

TEST_F(RapidJson, internal_Pow10) {
295 296 297 298
    double sum = 0;
    for (size_t i = 0; i < kTrialCount * kTrialCount; i++)
        sum += internal::Pow10(int(i & 255));
    EXPECT_GT(sum, 0.0);
299 300
}

301
TEST_F(RapidJson, SkipWhitespace_Basic) {
302
    for (size_t i = 0; i < kTrialCount; i++) {
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
        rapidjson::StringStream s(whitespace_);
        while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
            s.Take();
        ASSERT_EQ('[', s.Peek());
    }
}

TEST_F(RapidJson, SIMD_SUFFIX(SkipWhitespace)) {
    for (size_t i = 0; i < kTrialCount; i++) {
        rapidjson::StringStream s(whitespace_);
        rapidjson::SkipWhitespace(s);
        ASSERT_EQ('[', s.Peek());
    }
}

TEST_F(RapidJson, SkipWhitespace_strspn) {
    for (size_t i = 0; i < kTrialCount; i++) {
        const char* s = whitespace_ + std::strspn(whitespace_, " \t\r\n");
        ASSERT_EQ('[', *s);
    }
323 324
}

325
TEST_F(RapidJson, UTF8_Validate) {
326 327 328 329 330 331 332 333 334
    NullStream os;

    for (size_t i = 0; i < kTrialCount; i++) {
        StringStream is(json_);
        bool result = true;
        while (is.Peek() != '\0')
            result &= UTF8<>::Validate(is, os);
        EXPECT_TRUE(result);
    }
335 336
}

337
TEST_F(RapidJson, FileReadStream) {
338 339 340 341 342 343 344 345
    for (size_t i = 0; i < kTrialCount; i++) {
        FILE *fp = fopen(filename_, "rb");
        char buffer[65536];
        FileReadStream s(fp, buffer, sizeof(buffer));
        while (s.Take() != '\0')
            ;
        fclose(fp);
    }
346 347
}

348
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FileReadStream)) {
349 350 351 352 353 354 355 356 357
    for (size_t i = 0; i < kTrialCount; i++) {
        FILE *fp = fopen(filename_, "rb");
        char buffer[65536];
        FileReadStream s(fp, buffer, sizeof(buffer));
        BaseReaderHandler<> h;
        Reader reader;
        reader.Parse(s, h);
        fclose(fp);
    }
358 359
}

360
#endif // TEST_RAPIDJSON