| /* | 
 |  * Copyright 2018 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "Benchmark.h" | 
 | #include "SkData.h" | 
 | #include "SkJSON.h" | 
 | #include "SkStream.h" | 
 |  | 
 | #if defined(SK_BUILD_FOR_ANDROID) | 
 | static constexpr const char* kBenchFile = "/data/local/tmp/bench.json"; | 
 | #else | 
 | static constexpr const char* kBenchFile = "/tmp/bench.json"; | 
 | #endif | 
 |  | 
 | class JsonBench : public Benchmark { | 
 | public: | 
 |  | 
 | protected: | 
 |     const char* onGetName() override { return "json_skjson"; } | 
 |  | 
 |     bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } | 
 |  | 
 |     void onPerCanvasPreDraw(SkCanvas*) override { | 
 |         fData = SkData::MakeFromFileName(kBenchFile); | 
 |         if (!fData) { | 
 |             SkDebugf("!! Could not open bench file: %s\n", kBenchFile); | 
 |         } | 
 |     } | 
 |  | 
 |     void onPerCanvasPostDraw(SkCanvas*) override { | 
 |         fData = nullptr; | 
 |     } | 
 |  | 
 |     void onDraw(int loops, SkCanvas*) override { | 
 |         if (!fData) return; | 
 |  | 
 |         for (int i = 0; i < loops; i++) { | 
 |             skjson::DOM dom(static_cast<const char*>(fData->data()), fData->size()); | 
 |             if (dom.root().is<skjson::NullValue>()) { | 
 |                 SkDebugf("!! Parsing failed.\n"); | 
 |                 return; | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 | private: | 
 |     sk_sp<SkData> fData; | 
 |  | 
 |     using INHERITED = Benchmark; | 
 | }; | 
 |  | 
 | DEF_BENCH( return new JsonBench; ) | 
 |  | 
 | #if (0) | 
 |  | 
 | #include "rapidjson/document.h" | 
 |  | 
 | class RapidJsonBench : public Benchmark { | 
 | public: | 
 |  | 
 | protected: | 
 |     const char* onGetName() override { return "json_rapidjson"; } | 
 |  | 
 |     bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } | 
 |  | 
 |     void onPerCanvasPreDraw(SkCanvas*) override { | 
 |         if (auto stream = SkStream::MakeFromFile(kBenchFile)) { | 
 |             SkASSERT(stream->hasLength()); | 
 |             fCStringData = SkData::MakeUninitialized(stream->getLength() + 1); | 
 |             auto* data8 = reinterpret_cast<uint8_t*>(fCStringData->writable_data()); | 
 |             SkAssertResult(stream->read(data8, stream->getLength()) == stream->getLength()); | 
 |             data8[stream->getLength()] = '\0'; | 
 |  | 
 |         } else { | 
 |             SkDebugf("!! Could not open bench file: %s\n", kBenchFile); | 
 |         } | 
 |     } | 
 |  | 
 |     void onPerCanvasPostDraw(SkCanvas*) override { | 
 |         fCStringData = nullptr; | 
 |     } | 
 |  | 
 |     void onDraw(int loops, SkCanvas*) override { | 
 |         if (!fCStringData) return; | 
 |  | 
 |         for (int i = 0; i < loops; i++) { | 
 |             rapidjson::Document doc; | 
 |             doc.Parse(static_cast<const char*>(fCStringData->data())); | 
 |             if (doc.HasParseError()) { | 
 |                 SkDebugf("!! Parsing failed.\n"); | 
 |                 return; | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 | private: | 
 |     sk_sp<SkData> fCStringData; | 
 |  | 
 |     using INHERITED = Benchmark; | 
 | }; | 
 |  | 
 | DEF_BENCH( return new RapidJsonBench; ) | 
 |  | 
 | #endif | 
 |  | 
 | #if (0) | 
 |  | 
 | #include "pjson.h" | 
 |  | 
 | class PJsonBench : public Benchmark { | 
 | public: | 
 |  | 
 | protected: | 
 |     const char* onGetName() override { return "json_pjson"; } | 
 |  | 
 |     bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; } | 
 |  | 
 |     void onPerCanvasPreDraw(SkCanvas*) override { | 
 |         if (auto stream = SkStream::MakeFromFile(kBenchFile)) { | 
 |             SkASSERT(stream->hasLength()); | 
 |             fCStringData = SkData::MakeUninitialized(stream->getLength() + 1); | 
 |             auto* data8 = reinterpret_cast<uint8_t*>(fCStringData->writable_data()); | 
 |             SkAssertResult(stream->read(data8, stream->getLength()) == stream->getLength()); | 
 |             data8[stream->getLength()] = '\0'; | 
 |  | 
 |         } else { | 
 |             SkDebugf("!! Could not open bench file: %s\n", kBenchFile); | 
 |         } | 
 |     } | 
 |  | 
 |     void onPerCanvasPostDraw(SkCanvas*) override { | 
 |         fCStringData = nullptr; | 
 |     } | 
 |  | 
 |     void onDraw(int loops, SkCanvas*) override { | 
 |         if (!fCStringData) return; | 
 |  | 
 |         for (int i = 0; i < loops; i++) { | 
 |             // Copy needed for in-place operation. | 
 |             auto data = SkData::MakeWithCopy(fCStringData->data(), fCStringData->size()); | 
 |             pjson::document doc; | 
 |             if (!doc.deserialize_in_place(static_cast<char*>(data->writable_data()))) { | 
 |                 SkDebugf("!! Parsing failed.\n"); | 
 |                 return; | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 | private: | 
 |     sk_sp<SkData> fCStringData; | 
 |  | 
 |     using INHERITED = Benchmark; | 
 | }; | 
 |  | 
 | DEF_BENCH( return new PJsonBench; ) | 
 |  | 
 | #endif |