summaryrefslogtreecommitdiffstats
path: root/benchmark/threaded_json_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'benchmark/threaded_json_parser.cpp')
-rw-r--r--benchmark/threaded_json_parser.cpp209
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;
+}