diff --git a/README.md b/README.md index ef4beac21..1e0750b9d 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Table of Contents ----------------- * [Quick Start](#quick-start) + * [On Demand](#on-demand) * [Documentation](#documentation) * [Performance results](#performance-results) * [Real-world usage](#real-world-usage) @@ -40,11 +41,14 @@ Table of Contents Quick Start ----------- - The simdjson library is easily consumable with a single .h and .cpp file. -0. Prerequisites: `g++` (version 7 or better) or `clang++` (version 6 or better), and a 64-bit system with a command-line shell (e.g., Linux, macOS, freeBSD). We also support programming environments like Visual Studio and Xcode, but different steps are needed. -1. Pull [simdjson.h](singleheader/simdjson.h) and [simdjson.cpp](singleheader/simdjson.cpp) into a directory, along with the sample file [twitter.json](jsonexamples/twitter.json). +0. Prerequisites: `g++` (version 7 or better) or `clang++` (version 6 or better), and a 64-bit + system with a command-line shell (e.g., Linux, macOS, freeBSD). We also support programming + environments like Visual Studio and Xcode, but different steps are needed. +1. Pull [simdjson.h](singleheader/simdjson.h) and [simdjson.cpp](singleheader/simdjson.cpp) into a + directory, along with the sample file [twitter.json](jsonexamples/twitter.json). + ``` wget https://raw.githubusercontent.com/simdjson/simdjson/master/singleheader/simdjson.h https://raw.githubusercontent.com/simdjson/simdjson/master/singleheader/simdjson.cpp https://raw.githubusercontent.com/simdjson/simdjson/master/jsonexamples/twitter.json ``` @@ -64,6 +68,35 @@ The simdjson library is easily consumable with a single .h and .cpp file. 100 results. ``` +### On Demand + +The new On Demand JSON parser is just as easy, but much faster due to just-in-time parsing. It is in +alpha right now. More information can be found in the [On Demand Guide](doc/ondemand.md). + +1. Do step 1 of the [Quick Start](#quick-start). +2. Create `quickstart.cpp`: + + ```c++ + #include "simdjson.h" + using namespace simdjson; + using namespace simdjson::builtin; // for ondemand + int main(void) { + ondemand::parser parser; + padded_string json = padded_string::load("twitter.json"); + ondemand::document tweets = parser.iterate(json); + std::cout << uint64_t(tweets["search_metadata"]["count"]) << " results." << std::endl; + } + ``` +3. `c++ -march=native -o quickstart quickstart.cpp simdjson.cpp` +4. `./quickstart` + ``` + 100 results. + ``` + +You'll notice that the code here is very similar to the [main Quick Start code](#quick-start) (and +indeed, it does the same thing). However, if you compare the performance, you should find On +Demand much faster. + Documentation ------------- diff --git a/examples/quickstart/CMakeLists.txt b/examples/quickstart/CMakeLists.txt index 8c1a8c942..cae8c7774 100644 --- a/examples/quickstart/CMakeLists.txt +++ b/examples/quickstart/CMakeLists.txt @@ -10,56 +10,29 @@ # to do but that is not trivial. # IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - # TODO run amalgamate first! - function(add_quickstart_test TEST_NAME SOURCE_FILE) - # Second argument is C++ standard name - if (MSVC) - if (ARGV2) - set(QUICKSTART_FLAGS /std:${ARGV2}) - else() - set(QUICKSTART_FLAGS /WX) - endif() - set(QUICKSTART_INCLUDE /I${PROJECT_SOURCE_DIR}/include /I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp) - else() - if (ARGV2) - set(QUICKSTART_FLAGS -Werror -std=${ARGV2}) - else() - set(QUICKSTART_FLAGS -Werror) - endif() - set(QUICKSTART_INCLUDE -I${PROJECT_SOURCE_DIR}/include -I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp) - endif() - - # Third argument tells whether to compile with -fno-exceptions - if (ARGV3) - if (NOT MSVC) - set(QUICKSTART_FLAGS ${QUICKSTART_FLAGS} -fno-exceptions) - endif() - endif() - - add_test( - NAME ${TEST_NAME} - COMMAND ${CMAKE_CXX_COMPILER} ${QUICKSTART_FLAGS} -I${PROJECT_SOURCE_DIR}/include -I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp ${SOURCE_FILE} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/examples/quickstart - ) - set_property( - TEST ${TEST_NAME} - APPEND PROPERTY DEPENDS simdjson-source ${PROJECT_SOURCE_DIR}/examples/quickstart/${SOURCE_FILE} - ) - endfunction(add_quickstart_test) + include(add_quickstart_test.cmake) + # DOM Quick Start if (SIMDJSON_EXCEPTIONS) - add_quickstart_test(quickstart quickstart.cpp) - add_quickstart_test(quickstart11 quickstart.cpp c++11) - add_quickstart_test(quickstart14 quickstart.cpp c++14) - set_property( TEST quickstart quickstart11 APPEND PROPERTY LABELS acceptance compiletests no_mingw) + add_quickstart_test(quickstart quickstart.cpp LABELS acceptance) + add_quickstart_test(quickstart11 quickstart.cpp CXX_STANDARD c++11 LABELS acceptance) + add_quickstart_test(quickstart14 quickstart.cpp CXX_STANDARD c++14) endif() - add_quickstart_test(quickstart_noexceptions quickstart_noexceptions.cpp "" true) - add_quickstart_test(quickstart_noexceptions11 quickstart_noexceptions.cpp c++11 true) - set_property( TEST quickstart_noexceptions APPEND PROPERTY LABELS acceptance compile no_mingw) + add_quickstart_test(quickstart_noexceptions quickstart_noexceptions.cpp NO_EXCEPTIONS LABELS acceptance) + add_quickstart_test(quickstart_noexceptions11 quickstart_noexceptions.cpp NO_EXCEPTIONS CXX_STANDARD c++11) - add_quickstart_test(quickstart2_noexceptions quickstart2_noexceptions.cpp "" true) - add_quickstart_test(quickstart2_noexceptions11 quickstart2_noexceptions.cpp c++11 true) - set_property( TEST quickstart2_noexceptions APPEND PROPERTY LABELS acceptance compile no_mingw) + add_quickstart_test(quickstart2_noexceptions quickstart2_noexceptions.cpp NO_EXCEPTIONS LABELS acceptance) + add_quickstart_test(quickstart2_noexceptions11 quickstart2_noexceptions.cpp NO_EXCEPTIONS CXX_STANDARD c++11) + + # On Demand Quick Start + if (SIMDJSON_EXCEPTIONS) + add_quickstart_test(quickstart_ondemand quickstart_ondemand.cpp LABELS quickstart_ondemand acceptance) + add_quickstart_test(quickstart_ondemand11 quickstart_ondemand.cpp CXX_STANDARD c++11 LABELS quickstart_ondemand acceptance) + add_quickstart_test(quickstart_ondemand14 quickstart_ondemand.cpp CXX_STANDARD c++14 LABELS quickstart_ondemand) + endif() + + add_quickstart_test(quickstart_ondemand_noexceptions quickstart_ondemand_noexceptions.cpp NO_EXCEPTIONS LABELS quickstart_ondemand acceptance) + add_quickstart_test(quickstart_ondemand_noexceptions11 quickstart_ondemand_noexceptions.cpp NO_EXCEPTIONS CXX_STANDARD c++11 LABELS quickstart_ondemand) endif() diff --git a/examples/quickstart/add_quickstart_test.cmake b/examples/quickstart/add_quickstart_test.cmake new file mode 100644 index 000000000..4c965df5b --- /dev/null +++ b/examples/quickstart/add_quickstart_test.cmake @@ -0,0 +1,50 @@ +# TODO run amalgamate first! +function(add_quickstart_test TEST_NAME SOURCE_FILE) + cmake_parse_arguments(PARSE_ARGV 2 ARGS "NO_EXCEPTIONS;NATIVE_ARCH" "" "CXX_STANDARD;LABELS") + + # Standard compiler flags + if (MSVC) + list(APPEND QUICKSTART_FLAGS /WX) + else() + list(APPEND QUICKSTART_FLAGS -Werror) + endif() + + # Native architecture compiler flag + if (ARGS_NATIVE_ARCH) + if (MSVC) + message(ERROR "MSVC quickstart native compile not supported because we don't know the right flag to pass to MSVC yet") + else() + list(APPEND QUICKSTART_FLAGS -march=native) + endif() + endif() + + # C++ standard compiler flag + if (MSVC) + if (ARGS_CXX_STANDARD) + list(APPEND QUICKSTART_FLAGS /std:${ARGS_CXX_STANDARD}) + endif() + else() + if (ARGS_CXX_STANDARD) + list(APPEND QUICKSTART_FLAGS -std=${ARGS_CXX_STANDARD}) + endif() + endif() + + # No Exceptions compiler flag + if (ARGS_NO_EXCEPTIONS) + if (NOT MSVC) + list(APPEND QUICKSTART_FLAGS -fno-exceptions) + endif() + endif() + + add_test( + NAME ${TEST_NAME} + COMMAND ${CMAKE_CXX_COMPILER} ${QUICKSTART_FLAGS} -I${PROJECT_SOURCE_DIR}/include -I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp ${SOURCE_FILE} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/examples/quickstart + ) + list(APPEND ARGS_LABELS quickstart compile no_mingw) + set_property(TEST ${TEST_NAME} APPEND PROPERTY LABELS ${ARGS_LABELS}) + set_property( + TEST ${TEST_NAME} + APPEND PROPERTY DEPENDS simdjson-source ${PROJECT_SOURCE_DIR}/examples/quickstart/${SOURCE_FILE} + ) +endfunction(add_quickstart_test) diff --git a/examples/quickstart/quickstart_ondemand.cpp b/examples/quickstart/quickstart_ondemand.cpp new file mode 100644 index 000000000..0a5a69ea9 --- /dev/null +++ b/examples/quickstart/quickstart_ondemand.cpp @@ -0,0 +1,9 @@ +#include "simdjson.h" +using namespace simdjson; +using namespace simdjson::builtin; // for ondemand +int main(void) { + ondemand::parser parser; + padded_string json = padded_string::load("twitter.json"); + ondemand::document tweets = parser.iterate(json); + std::cout << uint64_t(tweets["search_metadata"]["count"]) << " results." << std::endl; +} diff --git a/examples/quickstart/quickstart_ondemand_noexceptions.cpp b/examples/quickstart/quickstart_ondemand_noexceptions.cpp new file mode 100644 index 000000000..e00d02625 --- /dev/null +++ b/examples/quickstart/quickstart_ondemand_noexceptions.cpp @@ -0,0 +1,19 @@ +#include "simdjson.h" +int main(void) { + simdjson::padded_string json; + auto error = simdjson::padded_string::load("twitter.json").get(json); + if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } + + simdjson::builtin::ondemand::parser parser; + simdjson::builtin::ondemand::document tweets; + error = parser.iterate(json).get(tweets); + if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } + + uint64_t count; + error = tweets["search_metadata"]["count"].get(count); + if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } + + std::cout << count << " results." << std::endl; + + return EXIT_SUCCESS; +}