From 04267e0f6b711b8883c8bd5f2c4b3d0761bf459b Mon Sep 17 00:00:00 2001 From: Paul Dreik Date: Sun, 4 Oct 2020 10:00:09 +0200 Subject: [PATCH] add boost.json to benchmark (#1202) Add boost.json to the benchmark. It was accepted into boost 20201003, see https://lists.boost.org/Archives/boost/2020/10/250129.php. The upstream repo is (expected to eventually be migrated to boost): https://github.com/CPPAlliance/json --- .gitmodules | 3 + benchmark/CMakeLists.txt | 4 + benchmark/benchmark.h | 67 ++++----- benchmark/parsingcompetition.cpp | 227 ++++++++++++++++++------------- dependencies/CMakeLists.txt | 11 +- dependencies/boost.json | 1 + 6 files changed, 187 insertions(+), 126 deletions(-) create mode 160000 dependencies/boost.json diff --git a/.gitmodules b/.gitmodules index 4622e878..a66342b0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -34,3 +34,6 @@ [submodule "dependencies/cxxopts"] path = dependencies/cxxopts url = https://github.com/jarro2783/cxxopts +[submodule "dependencies/boost.json"] + path = dependencies/boost.json + url = https://github.com/CPPAlliance/json.git diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index d9bae0fe..606796c0 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -25,12 +25,16 @@ target_compile_definitions(parse_nostringparsing PRIVATE SIMDJSON_SKIPSTRINGPARS if (TARGET competition-all) add_executable(distinctuseridcompetition distinctuseridcompetition.cpp) target_link_libraries(distinctuseridcompetition competition-core) + add_executable(minifiercompetition minifiercompetition.cpp) target_link_libraries(minifiercompetition competition-core) + add_executable(parseandstatcompetition parseandstatcompetition.cpp) target_link_libraries(parseandstatcompetition competition-core) + add_executable(parsingcompetition parsingcompetition.cpp) target_link_libraries(parsingcompetition competition-core) + add_executable(allparsingcompetition parsingcompetition.cpp) target_link_libraries(allparsingcompetition competition-all) target_compile_definitions(allparsingcompetition PRIVATE ALLPARSER) diff --git a/benchmark/benchmark.h b/benchmark/benchmark.h index 836f8507..7e043aa5 100644 --- a/benchmark/benchmark.h +++ b/benchmark/benchmark.h @@ -12,9 +12,9 @@ #define BEST_TIME(name, test, expected, pre, repeat, size, verbose) \ do { \ if (verbose) \ - printf("%-40s\t: ", name); \ + std::printf("%-40s\t: ", name); \ else \ - printf("\"%-40s\"", name); \ + std::printf("\"%-40s\"", name); \ fflush(NULL); \ event_collector collector; \ event_aggregate aggregate{}; \ @@ -23,7 +23,8 @@ std::atomic_thread_fence(std::memory_order_acquire); \ collector.start(); \ if (test != expected) { \ - fprintf(stderr, "not expected (%d , %d )", (int)test, (int)expected); \ + std::fprintf(stderr, "not expected (%d , %d )", (int)test, \ + (int)expected); \ break; \ } \ std::atomic_thread_fence(std::memory_order_release); \ @@ -31,39 +32,40 @@ aggregate << allocate_count; \ } \ if (collector.has_events()) { \ - printf("%7.3f", aggregate.best.cycles() / static_cast(size)); \ + std::printf("%7.3f", \ + aggregate.best.cycles() / static_cast(size)); \ if (verbose) { \ - printf(" cycles/byte "); \ + std::printf(" cycles/byte "); \ } \ - printf("\t"); \ - printf("%7.3f", \ - aggregate.best.instructions() / static_cast(size)); \ + std::printf("\t"); \ + std::printf("%7.3f", \ + aggregate.best.instructions() / static_cast(size)); \ if (verbose) { \ - printf(" instructions/byte "); \ + std::printf(" instructions/byte "); \ } \ - printf("\t"); \ + std::printf("\t"); \ } \ double gb = static_cast(size) / 1000000000.0; \ - printf("%7.3f", gb / aggregate.best.elapsed_sec()); \ + std::printf("%7.3f", gb / aggregate.best.elapsed_sec()); \ if (verbose) { \ - printf(" GB/s "); \ + std::printf(" GB/s "); \ } \ - printf("%7.3f", 1.0 / aggregate.best.elapsed_sec()); \ + std::printf("%7.3f", 1.0 / aggregate.best.elapsed_sec()); \ if (verbose) { \ - printf(" documents/s "); \ + std::printf(" documents/s "); \ } \ - printf("\n"); \ - fflush(NULL); \ + std::printf("\n"); \ + std::fflush(NULL); \ } while (0) // like BEST_TIME, but no check #define BEST_TIME_NOCHECK(name, test, pre, repeat, size, verbose) \ do { \ if (verbose) \ - printf("%-40s\t: ", name); \ + std::printf("%-40s\t: ", name); \ else \ - printf("\"%-40s\"", name); \ - fflush(NULL); \ + std::printf("\"%-40s\"", name); \ + std::fflush(NULL); \ event_collector collector; \ event_aggregate aggregate{}; \ for (decltype(repeat) i = 0; i < repeat; i++) { \ @@ -76,29 +78,30 @@ aggregate << allocate_count; \ } \ if (collector.has_events()) { \ - printf("%7.3f", aggregate.best.cycles() / static_cast(size)); \ + std::printf("%7.3f", \ + aggregate.best.cycles() / static_cast(size)); \ if (verbose) { \ - printf(" cycles/byte "); \ + std::printf(" cycles/byte "); \ } \ - printf("\t"); \ - printf("%7.3f", \ - aggregate.best.instructions() / static_cast(size)); \ + std::printf("\t"); \ + std::printf("%7.3f", \ + aggregate.best.instructions() / static_cast(size)); \ if (verbose) { \ - printf(" instructions/byte "); \ + std::printf(" instructions/byte "); \ } \ - printf("\t"); \ + std::printf("\t"); \ } \ double gb = static_cast(size) / 1000000000.0; \ - printf("%7.3f", gb / aggregate.best.elapsed_sec()); \ + std::printf("%7.3f", gb / aggregate.best.elapsed_sec()); \ if (verbose) { \ - printf(" GB/s "); \ + std::printf(" GB/s "); \ } \ - printf("%7.3f", 1.0 / aggregate.best.elapsed_sec()); \ + std::printf("%7.3f", 1.0 / aggregate.best.elapsed_sec()); \ if (verbose) { \ - printf(" documents/s "); \ + std::printf(" documents/s "); \ } \ - printf("\n"); \ - fflush(NULL); \ + std::printf("\n"); \ + std::fflush(NULL); \ } while (0) #endif diff --git a/benchmark/parsingcompetition.cpp b/benchmark/parsingcompetition.cpp index a63fbc89..674534cd 100644 --- a/benchmark/parsingcompetition.cpp +++ b/benchmark/parsingcompetition.cpp @@ -26,6 +26,8 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS #include using json = nlohmann::json; +#include + #ifdef ALLPARSER #include "fastjson.cpp" @@ -65,32 +67,35 @@ bool fastjson_parse(const char *input) { // end of fastjson stuff #endif -simdjson_never_inline size_t sum_line_lengths(std::stringstream & is) { +simdjson_never_inline size_t sum_line_lengths(std::stringstream &is) { std::string line; size_t sumofalllinelengths{0}; - while(std::getline(is, line)) { + while (std::getline(is, line)) { sumofalllinelengths += line.size(); } return sumofalllinelengths; } -inline void reset_stream(std::stringstream & is) { +inline void reset_stream(std::stringstream &is) { is.clear(); - is.seekg(0,std::ios::beg); + is.seekg(0, std::ios::beg); } - - -bool bench(const char *filename, bool verbose, bool just_data, double repeat_multiplier) { +bool bench(const char *filename, bool verbose, bool just_data, + double repeat_multiplier) { simdjson::padded_string p; auto error = simdjson::padded_string::load(filename).get(p); if (error) { - std::cerr << "Could not load the file " << filename << ": " << error << std::endl; + std::cerr << "Could not load the file " << filename << ": " << error + << std::endl; return false; } - int repeat = static_cast((50000000 * repeat_multiplier) / static_cast(p.size())); - if (repeat < 10) { repeat = 10; } + int repeat = static_cast((50000000 * repeat_multiplier) / + static_cast(p.size())); + if (repeat < 10) { + repeat = 10; + } // Gigabyte: https://en.wikipedia.org/wiki/Gigabyte if (verbose) { std::cout << "Input " << filename << " has "; @@ -104,68 +109,81 @@ bool bench(const char *filename, bool verbose, bool just_data, double repeat_mul } size_t volume = p.size(); if (just_data) { - printf("%-42s %20s %20s %20s %20s \n", "name", "cycles_per_byte", - "cycles_per_byte_err", "gb_per_s", "gb_per_s_err"); + std::printf("%-42s %20s %20s %20s %20s \n", "name", "cycles_per_byte", + "cycles_per_byte_err", "gb_per_s", "gb_per_s_err"); } if (!just_data) { - const std::string inputcopy(p.data(), p.data()+p.size()); + const std::string inputcopy(p.data(), p.data() + p.size()); std::stringstream is; is.str(inputcopy); const size_t lc = sum_line_lengths(is); - BEST_TIME("getline ",sum_line_lengths(is) , lc, reset_stream(is), - repeat, volume, !just_data); + BEST_TIME("getline ", sum_line_lengths(is), lc, reset_stream(is), repeat, + volume, !just_data); } if (!just_data) { - auto parse_dynamic=[](auto& str){ - simdjson::dom::parser parser; - return parser.parse(str).error(); + auto parse_dynamic = [](auto &str) { + simdjson::dom::parser parser; + return parser.parse(str).error(); }; - BEST_TIME("simdjson (dynamic mem) ", parse_dynamic(p), simdjson::SUCCESS, - , repeat, volume, !just_data); + BEST_TIME("simdjson (dynamic mem) ", parse_dynamic(p), simdjson::SUCCESS, , + repeat, volume, !just_data); } // (static alloc) simdjson::dom::parser parser; - BEST_TIME("simdjson ", parser.parse(p).error(), simdjson::SUCCESS, , repeat, volume, - !just_data); - + BEST_TIME("simdjson ", parser.parse(p).error(), simdjson::SUCCESS, , repeat, + volume, !just_data); + rapidjson::Document d; - char *buffer = (char *)malloc(p.size() + 1); - memcpy(buffer, p.data(), p.size()); + char *buffer = (char *)std::malloc(p.size() + 1); + std::memcpy(buffer, p.data(), p.size()); buffer[p.size()] = '\0'; #ifndef ALLPARSER if (!just_data) #endif { - memcpy(buffer, p.data(), p.size()); + std::memcpy(buffer, p.data(), p.size()); BEST_TIME("RapidJSON ", d.Parse((const char *)buffer) .HasParseError(), - false, , repeat, volume, - !just_data); + false, , repeat, volume, !just_data); } #ifndef ALLPARSER if (!just_data) #endif { - memcpy(buffer, p.data(), p.size()); + std::memcpy(buffer, p.data(), p.size()); BEST_TIME("RapidJSON (accurate number parsing) ", - d.Parse((const char *)buffer) + d.Parse( + (const char *)buffer) .HasParseError(), - false, , repeat, volume, - !just_data); + false, , repeat, volume, !just_data); } - BEST_TIME("RapidJSON (insitu)", - d.ParseInsitu(buffer).HasParseError(), - false, - memcpy(buffer, p.data(), p.size()) && (buffer[p.size()] = '\0'), - repeat, volume, !just_data); + BEST_TIME( + "RapidJSON (insitu)", + d.ParseInsitu(buffer).HasParseError(), false, + std::memcpy(buffer, p.data(), p.size()) && (buffer[p.size()] = '\0'), + repeat, volume, !just_data); BEST_TIME("RapidJSON (insitu, accurate number parsing)", - d.ParseInsitu(buffer).HasParseError(), + d.ParseInsitu( + buffer) + .HasParseError(), false, - memcpy(buffer, p.data(), p.size()) && (buffer[p.size()] = '\0'), + std::memcpy(buffer, p.data(), p.size()) && + (buffer[p.size()] = '\0'), repeat, volume, !just_data); + + { + const boost::json::string_view sv(p.data(), p.size()); + auto execute = [](auto sv) -> bool { + boost::json::error_code ec; + auto jv = boost::json::parse(sv, ec); + return !!ec; + }; + + BEST_TIME("Boost.json", execute(sv), false, , repeat, volume, !just_data); + } #ifndef ALLPARSER if (!just_data) #endif @@ -173,59 +191,61 @@ bool bench(const char *filename, bool verbose, bool just_data, double repeat_mul sajson::parse(sajson::dynamic_allocation(), sajson::mutable_string_view(p.size(), buffer)) .is_valid(), - true, memcpy(buffer, p.data(), p.size()), repeat, volume, + true, std::memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data); size_t ast_buffer_size = p.size(); - size_t *ast_buffer = (size_t *)malloc(ast_buffer_size * sizeof(size_t)); + size_t *ast_buffer = (size_t *)std::malloc(ast_buffer_size * sizeof(size_t)); // (static alloc, insitu) BEST_TIME( "sajson", sajson::parse(sajson::bounded_allocation(ast_buffer, ast_buffer_size), sajson::mutable_string_view(p.size(), buffer)) .is_valid(), - true, memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data); + true, std::memcpy(buffer, p.data(), p.size()), repeat, volume, + !just_data); - memcpy(buffer, p.data(), p.size()); + std::memcpy(buffer, p.data(), p.size()); size_t expected = json::parse(p.data(), p.data() + p.size()).size(); BEST_TIME("nlohmann-json", json::parse(buffer, buffer + p.size()).size(), - expected, , repeat, volume, - !just_data); + expected, , repeat, volume, !just_data); #ifdef ALLPARSER std::string json11err; BEST_TIME("dropbox (json11) ", ((json11::Json::parse(buffer, json11err).is_null()) || (!json11err.empty())), - false, memcpy(buffer, p.data(), p.size()), repeat, volume, + false, std::memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data); BEST_TIME("fastjson ", fastjson_parse(buffer), true, - memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data); + std::memcpy(buffer, p.data(), p.size()), repeat, volume, + !just_data); JsonValue value; JsonAllocator allocator; char *endptr; BEST_TIME("gason ", jsonParse(buffer, &endptr, &value, allocator), - JSON_OK, memcpy(buffer, p.data(), p.size()), repeat, volume, + JSON_OK, std::memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data); void *state; BEST_TIME("ultrajson ", (UJDecode(buffer, p.size(), NULL, &state) == NULL), false, - memcpy(buffer, p.data(), p.size()), repeat, volume, !just_data); + std::memcpy(buffer, p.data(), p.size()), repeat, volume, + !just_data); { std::unique_ptr tokens = std::make_unique(p.size()); jsmn_parser jparser; jsmn_init(&jparser); - memcpy(buffer, p.data(), p.size()); + std::memcpy(buffer, p.data(), p.size()); buffer[p.size()] = '\0'; - BEST_TIME( - "jsmn ", - (jsmn_parse(&jparser, buffer, p.size(), tokens.get(), static_cast(p.size())) > 0), - true, jsmn_init(&jparser), repeat, volume, !just_data); + BEST_TIME("jsmn ", + (jsmn_parse(&jparser, buffer, p.size(), tokens.get(), + static_cast(p.size())) > 0), + true, jsmn_init(&jparser), repeat, volume, !just_data); } - memcpy(buffer, p.data(), p.size()); + std::memcpy(buffer, p.data(), p.size()); buffer[p.size()] = '\0'; cJSON *tree = cJSON_Parse(buffer); BEST_TIME("cJSON ", ((tree = cJSON_Parse(buffer)) != NULL), true, @@ -243,12 +263,13 @@ bool bench(const char *filename, bool verbose, bool just_data, double repeat_mul #endif if (!just_data) BEST_TIME("memcpy ", - (memcpy(buffer, p.data(), p.size()) == buffer), true, , repeat, - volume, !just_data); + (std::memcpy(buffer, p.data(), p.size()) == buffer), true, , + repeat, volume, !just_data); #ifdef __linux__ if (!just_data) { - printf("\n \n \n"); + std::printf( + "\n \n \n"); std::vector evts; evts.push_back(PERF_COUNT_HW_CPU_CYCLES); evts.push_back(PERF_COUNT_HW_INSTRUCTIONS); @@ -265,64 +286,84 @@ bool bench(const char *filename, bool verbose, bool just_data, double repeat_mul unified.start(); auto parse_error = parser.parse(p).error(); if (parse_error) - printf("bug\n"); + std::printf("bug\n"); unified.end(results); std::transform(stats.begin(), stats.end(), results.begin(), stats.begin(), std::plus()); } - printf("simdjson : cycles %10.0f instructions %10.0f branchmisses %10.0f " - "cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f " - "inspercycle %10.1f insperbyte %10.1f\n", - static_cast(stats[0]) / static_cast(repeat), static_cast(stats[1]) / static_cast(repeat), - static_cast(stats[2]) / static_cast(repeat), static_cast(stats[3]) / static_cast(repeat), - static_cast(stats[4]) / static_cast(repeat), static_cast(volume) * static_cast(repeat) / static_cast(stats[2]), - static_cast(stats[1]) / static_cast(stats[0]), static_cast(stats[1]) / (static_cast(volume) * static_cast(repeat))); + std::printf( + "simdjson : cycles %10.0f instructions %10.0f branchmisses %10.0f " + "cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f " + "inspercycle %10.1f insperbyte %10.1f\n", + static_cast(stats[0]) / static_cast(repeat), + static_cast(stats[1]) / static_cast(repeat), + static_cast(stats[2]) / static_cast(repeat), + static_cast(stats[3]) / static_cast(repeat), + static_cast(stats[4]) / static_cast(repeat), + static_cast(volume) * static_cast(repeat) / + static_cast(stats[2]), + static_cast(stats[1]) / static_cast(stats[0]), + static_cast(stats[1]) / + (static_cast(volume) * static_cast(repeat))); std::fill(stats.begin(), stats.end(), 0); for (decltype(repeat) i = 0; i < repeat; i++) { - memcpy(buffer, p.data(), p.size()); + std::memcpy(buffer, p.data(), p.size()); buffer[p.size()] = '\0'; unified.start(); if (d.ParseInsitu(buffer).HasParseError() != false) - printf("bug\n"); + std::printf("bug\n"); unified.end(results); std::transform(stats.begin(), stats.end(), results.begin(), stats.begin(), std::plus()); } - printf("RapidJSON: cycles %10.0f instructions %10.0f branchmisses %10.0f " - "cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f " - "inspercycle %10.1f insperbyte %10.1f\n", - static_cast(stats[0]) / static_cast(repeat), static_cast(stats[1]) / static_cast(repeat), - static_cast(stats[2]) / static_cast(repeat), static_cast(stats[3]) / static_cast(repeat), - static_cast(stats[4]) / static_cast(repeat), static_cast(volume) * static_cast(repeat) / static_cast(stats[2]), - static_cast(stats[1]) / static_cast(stats[0]), static_cast(stats[1]) / (static_cast(volume) * static_cast(repeat))); + std::printf( + "RapidJSON: cycles %10.0f instructions %10.0f branchmisses %10.0f " + "cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f " + "inspercycle %10.1f insperbyte %10.1f\n", + static_cast(stats[0]) / static_cast(repeat), + static_cast(stats[1]) / static_cast(repeat), + static_cast(stats[2]) / static_cast(repeat), + static_cast(stats[3]) / static_cast(repeat), + static_cast(stats[4]) / static_cast(repeat), + static_cast(volume) * static_cast(repeat) / + static_cast(stats[2]), + static_cast(stats[1]) / static_cast(stats[0]), + static_cast(stats[1]) / + (static_cast(volume) * static_cast(repeat))); std::fill(stats.begin(), stats.end(), 0); // unnecessary for (decltype(repeat) i = 0; i < repeat; i++) { - memcpy(buffer, p.data(), p.size()); + std::memcpy(buffer, p.data(), p.size()); unified.start(); if (sajson::parse(sajson::bounded_allocation(ast_buffer, ast_buffer_size), sajson::mutable_string_view(p.size(), buffer)) .is_valid() != true) - printf("bug\n"); + std::printf("bug\n"); unified.end(results); std::transform(stats.begin(), stats.end(), results.begin(), stats.begin(), std::plus()); } - printf("sajson : cycles %10.0f instructions %10.0f branchmisses %10.0f " - "cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f " - "inspercycle %10.1f insperbyte %10.1f\n", - static_cast(stats[0]) / static_cast(repeat), static_cast(stats[1]) / static_cast(repeat), - static_cast(stats[2]) / static_cast(repeat), static_cast(stats[3]) / static_cast(repeat), - static_cast(stats[4]) / static_cast(repeat), static_cast(volume) * static_cast(repeat) / static_cast(stats[2]), - static_cast(stats[1]) / static_cast(stats[0]), static_cast(stats[1]) / (static_cast(volume) * static_cast(repeat))); - + std::printf( + "sajson : cycles %10.0f instructions %10.0f branchmisses %10.0f " + "cacheref %10.0f cachemisses %10.0f bytespercachemiss %10.0f " + "inspercycle %10.1f insperbyte %10.1f\n", + static_cast(stats[0]) / static_cast(repeat), + static_cast(stats[1]) / static_cast(repeat), + static_cast(stats[2]) / static_cast(repeat), + static_cast(stats[3]) / static_cast(repeat), + static_cast(stats[4]) / static_cast(repeat), + static_cast(volume) * static_cast(repeat) / + static_cast(stats[2]), + static_cast(stats[1]) / static_cast(stats[0]), + static_cast(stats[1]) / + (static_cast(volume) * static_cast(repeat))); } #endif // __linux__ - free(ast_buffer); - free(buffer); + std::free(ast_buffer); + std::free(buffer); return true; } @@ -349,13 +390,17 @@ int main(int argc, char *argv[]) { std::cerr << "Usage: " << argv[0] << " " << std::endl; std::cerr << "Or " << argv[0] << " -v " << std::endl; std::cerr << "The '-t' flag outputs a table." << std::endl; - std::cerr << "The '-r ' flag sets the repeat multiplier: set it above 1 to do more iterations, and below 1 to do fewer." << std::endl; + std::cerr << "The '-r ' flag sets the repeat multiplier: set it above 1 " + "to do more iterations, and below 1 to do fewer." + << std::endl; exit(1); } int result = EXIT_SUCCESS; for (int fileind = optind; fileind < argc; fileind++) { - if (!bench(argv[fileind], verbose, just_data, repeat_multiplier)) { result = EXIT_FAILURE; } - printf("\n\n"); + if (!bench(argv[fileind], verbose, just_data, repeat_multiplier)) { + result = EXIT_FAILURE; + } + std::printf("\n\n"); } return result; } diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt index 3c87489f..84e1b8d4 100644 --- a/dependencies/CMakeLists.txt +++ b/dependencies/CMakeLists.txt @@ -67,8 +67,13 @@ if ((Git_FOUND) AND SIMDJSON_GIT AND (SIMDJSON_IS_UNDER_GIT)) add_library(competition-ujson4c ujson4c/src/ujdecode.c) target_include_directories(competition-ujson4c PUBLIC ujson4c/3rdparty ujson4c/src) + initialize_submodule(boost.json) + add_library(boostjson boost.json/src/src.cpp) + target_compile_definitions(boostjson PUBLIC BOOST_JSON_STANDALONE) + target_include_directories(boostjson PUBLIC boost.json/include) + add_library(competition-core INTERFACE) - target_link_libraries(competition-core INTERFACE competition-json competition-rapidjson competition-sajson competition-cJSON competition-jsmn) + target_link_libraries(competition-core INTERFACE competition-json competition-rapidjson competition-sajson competition-cJSON competition-jsmn boostjson) add_library(competition-all INTERFACE) target_link_libraries(competition-all INTERFACE competition-core competition-jsoncppdist competition-json11 competition-fastjson competition-gason competition-ujson4c) @@ -81,9 +86,9 @@ if ((Git_FOUND) AND SIMDJSON_GIT AND (SIMDJSON_IS_UNDER_GIT)) else() message(STATUS "Git is unavailable.") if(SIMDJSON_COMPETITION) - message (STATUS "'SIMDJSON_COMPETITION' is requested, but we cannot download the remote repositories." ) + message (STATUS "'SIMDJSON_COMPETITION' is requested, but we cannot download the remote repositories." ) endif() if(SIMDJSON_GOOGLE_BENCHMARKS) message (STATUS "'SIMDJSON_GOOGLE_BENCHMARKS' is requested, but we cannot download the remote repositories." ) endif() -endif() \ No newline at end of file +endif() diff --git a/dependencies/boost.json b/dependencies/boost.json new file mode 160000 index 00000000..a0983f78 --- /dev/null +++ b/dependencies/boost.json @@ -0,0 +1 @@ +Subproject commit a0983f788b9138211bfc060e68c9973efb3394e4