diff --git a/BUILD.bazel b/BUILD.bazel index 06611a3d..c8f626a3 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -33,6 +33,7 @@ cc_binary( "@cJSON", "@yyjson", "@simdjson", + "@jsoncpp//:jsoncpp", ], copts = common_copts + ['-DNDEBUG', '-std=c++17'], linkopts = ['-lstdc++fs'], diff --git a/WORKSPACE b/WORKSPACE index 5ab31ecc..8dec9130 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -42,6 +42,12 @@ new_git_repository( remote = "https://github.com/ibireme/yyjson.git", ) +git_repository( + name = "jsoncpp", + branch = "master", + remote = "https://github.com/open-source-parsers/jsoncpp", +) + git_repository( name = "gflags", branch = "master", diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index c97e5de9..40d4b2f9 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -8,6 +8,7 @@ set(COMPILE_FLAGS -O3 -DNDEBUG -g -mavx2 -mpclmul -mbmi -mlzcnt) include("${PROJECT_SOURCE_DIR}/cmake/external.cmake") +unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY CACHE) add_executable(bench "${BENCH_SRC}") set(EP_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/external/) @@ -23,7 +24,7 @@ ExternalProject_Add( add_dependencies(bench google_benchmark) target_compile_features(bench PRIVATE cxx_std_17) -target_link_libraries(bench simdjson yyjson cjson benchmark benchmark_main pthread stdc++fs) +target_link_libraries(bench simdjson yyjson cjson jsoncpp_lib benchmark benchmark_main pthread stdc++fs) target_include_directories(bench PRIVATE ${rapidjson_SOURCE_DIR}/include PRIVATE ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR} @@ -31,6 +32,7 @@ target_include_directories(bench PRIVATE ${cjson_SOURCE_DIR}/ PRIVATE ${yyjson_SOURCE_DIR}/src/ PRIVATE ${simdjson_SOURCE_DIR}/singleheader/ + PRIVATE ${jsoncpp_SOURCE_DIR}/include/ ) target_link_directories(bench PRIVATE ${EP_PREFIX}/src/google_benchmark-build/src diff --git a/benchmark/jsoncpp.hpp b/benchmark/jsoncpp.hpp new file mode 100644 index 00000000..4b23ec51 --- /dev/null +++ b/benchmark/jsoncpp.hpp @@ -0,0 +1,82 @@ +/* + * Copyright 2022 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef _JsonCpp_HPP_ +#define _JsonCpp_HPP_ +#include "json.h" +#include "json/json.h" + +class JsonCppStringResult : public StringResult { + public: + std::string_view str_impl() const { return data.c_str(); } + std::string data; +}; + +class JsonCppParseResult + : public ParseResult { + public: + Json::Value document; + + JsonCppParseResult(std::string_view json) { (void)json; } + ~JsonCppParseResult() {} + + bool contains_impl(std::string_view key) const { + return document.isMember(key.data(), key.data() + key.size()); + } + + bool stringfy_impl(JsonCppStringResult &sr) const { + Json::StreamWriterBuilder writer_builder; + std::unique_ptr stream_writer( + writer_builder.newStreamWriter()); + std::ostringstream oss; + int res = stream_writer->write(document, &oss); + sr.data = oss.str(); + return (res == 0 && oss.good()); + } + + bool prettify_impl(JsonCppStringResult &sr) const { + (void)sr; + return false; + } + + bool stat_impl(DocStat &stat) const { + (void)stat; + return true; + } + + bool find_impl(DocStat &stat) const { + (void)stat; + return true; + } + + private: +}; + +class JsonCpp : public JsonBase { + public: + bool parse_impl(std::string_view json, JsonCppParseResult &pr) const { + Json::CharReaderBuilder reader_builder; + std::unique_ptr char_reader( + reader_builder.newCharReader()); + if (!char_reader->parse(json.data(), json.data() + json.size(), + &pr.document, nullptr)) { + return false; + } + return true; + } +}; + +#endif diff --git a/benchmark/main.cpp b/benchmark/main.cpp index 5ae6ac8b..70761063 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -23,6 +23,7 @@ #include #include "cjson.hpp" +#include "jsoncpp.hpp" #include "ondemand.hpp" #include "rapidjson.hpp" #include "simdjson.hpp" @@ -225,6 +226,7 @@ int main(int argc, char **argv) { ADD_JSON_BMK(Rapidjson, METHOD); \ ADD_JSON_BMK(YYjson, METHOD); \ ADD_JSON_BMK(SIMDjson, METHOD); \ + ADD_JSON_BMK(JsonCpp, METHOD); \ } \ } while (0) diff --git a/cmake/external.cmake b/cmake/external.cmake index 1626d269..c259ecfb 100644 --- a/cmake/external.cmake +++ b/cmake/external.cmake @@ -54,3 +54,9 @@ FetchContent_Declare( GIT_SHALLOW TRUE) FetchContent_MakeAvailable(yyjson) +FetchContent_Declare( + jsoncpp + GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp.git + GIT_TAG master + GIT_SHALLOW TRUE) +FetchContent_MakeAvailable(jsoncpp) \ No newline at end of file