diff options
Diffstat (limited to 'benchmark/threaded_json_parser.cpp')
-rw-r--r-- | benchmark/threaded_json_parser.cpp | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/benchmark/threaded_json_parser.cpp b/benchmark/threaded_json_parser.cpp new file mode 100644 index 0000000..f2e94fa --- /dev/null +++ b/benchmark/threaded_json_parser.cpp @@ -0,0 +1,209 @@ + +#include <orcus/stream.hpp> +#include <orcus/threaded_json_parser.hpp> +#include <orcus/string_pool.hpp> + +#include <vector> +#include <iostream> +#include <stdio.h> +#include <string> +#include <sys/time.h> + +#define SIMULATE_PROCESSING_OVERHEAD 0 + +using namespace std; +using namespace orcus; + +namespace { + +class stack_printer +{ +public: + explicit stack_printer(const char* msg) : + m_msg(msg) + { + fprintf(stdout, "%s: --begin\n", m_msg.c_str()); + m_start_time = get_time(); + } + + ~stack_printer() + { + double end_time = get_time(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", m_msg.c_str(), (end_time-m_start_time)); + } + +private: + double get_time() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string m_msg; + double m_start_time; +}; + +} + +class handler +{ + string_pool m_pool; + json::parse_tokens_t m_tokens; + std::vector<double> m_results; + + void do_work() + { +#if SIMULATE_PROCESSING_OVERHEAD + double f = m_results.empty() ? 0.0 : m_results.back(); + + for (size_t i = 0; i < 1000; ++i) + f += 0.1; + + m_results.push_back(f); +#endif + } + +public: + void begin_parse() + { + m_tokens.emplace_back(json::parse_token_t::begin_parse); + do_work(); + } + + void end_parse() + { + m_tokens.emplace_back(json::parse_token_t::end_parse); + do_work(); + } + + void begin_array() + { + m_tokens.emplace_back(json::parse_token_t::begin_array); + do_work(); + } + + void end_array() + { + m_tokens.emplace_back(json::parse_token_t::end_array); + do_work(); + } + + void begin_object() + { + m_tokens.emplace_back(json::parse_token_t::begin_object); + do_work(); + } + + void object_key(const char* p, size_t len, bool transient) + { + std::string_view s{p, len}; + if (transient) + s = m_pool.intern(s).first; + + m_tokens.emplace_back(json::parse_token_t::object_key, s); + do_work(); + } + + void end_object() + { + m_tokens.emplace_back(json::parse_token_t::end_object); + do_work(); + } + + void boolean_true() + { + m_tokens.emplace_back(json::parse_token_t::boolean_true); + do_work(); + } + + void boolean_false() + { + m_tokens.emplace_back(json::parse_token_t::boolean_false); + do_work(); + } + + void null() + { + m_tokens.emplace_back(json::parse_token_t::null); + do_work(); + } + + void string(const char* p, size_t len, bool transient) + { + std::string_view s{p, len}; + if (transient) + s = m_pool.intern(s).first; + + m_tokens.emplace_back(json::parse_token_t::string, s); + do_work(); + } + + void number(double val) + { + m_tokens.emplace_back(val); + do_work(); + } + + size_t token_size() const + { + return m_tokens.size(); + } + + double work_value() const + { + return m_results.back(); + } +}; + +int main(int argc, char** argv) try +{ + if (argc < 2) + return EXIT_FAILURE; + + const char* filepath = argv[1]; + orcus::file_content content(filepath); + + size_t min_token_size = 0; + size_t max_token_size = 0; + + if (argc >= 3) + { + const char* p = argv[2]; + min_token_size = strtol(p, nullptr, 10); + } + + if (argc >= 4) + { + const char* p = argv[3]; + max_token_size = strtol(p, nullptr, 10); + } + + cout << "file: " << filepath << endl; + cout << "min token size: " << min_token_size << endl; + cout << "max token size: " << max_token_size << endl; + + handler hdl; + orcus::json::parser_stats stats; + { + stack_printer __stack_printer__("parsing"); + orcus::threaded_json_parser<handler> parser(content.data(), content.size(), hdl, min_token_size, max_token_size); + parser.parse(); + + stats = parser.get_stats(); + } + + cout << "final token buffer size threshold: " << stats.token_buffer_size_threshold << endl; + + cout << "parsed token count: " << hdl.token_size() << endl; +#if SIMULATE_PROCESSING_OVERHEAD + cout << "work value: " << hdl.work_value() << endl; +#endif + + return EXIT_SUCCESS; +} +catch (const std::exception& e) +{ + cerr << e.what() << endl; + return EXIT_FAILURE; +} |