1
0
mirror of https://github.com/MoleskiCoder/EightBit.git synced 2025-01-11 17:29:57 +00:00

Add nlohmann json parser as an option to build.

1/2 speed, compared to boost.json

Signed-off-by: Adrian Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2021-10-11 14:59:23 +01:00
parent db106b1719
commit f3f6452119
14 changed files with 195 additions and 20 deletions

@ -169,6 +169,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="json_t.h" />
<ClInclude Include="nlohmann\json.hpp" />
<ClInclude Include="opcode_test_suite_t.h" />
<ClInclude Include="state_t.h" />
<ClInclude Include="stdafx.h" />

@ -52,5 +52,8 @@
<ClInclude Include="TestRunner.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="nlohmann\json.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -1,7 +1,6 @@
#include "stdafx.h"
#include "TestRunner.h"
#include <sstream>
#include <Disassembly.h>
TestRunner::TestRunner(const test_t& test)

@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include <sstream>
#include <string>
#include <vector>

@ -1,5 +1,8 @@
#include "stdafx.h"
#include "json_t.h"
#ifdef USE_BOOST_JSON
#include <cassert>
const boost::json::value& json_t::get_value(const boost::json::object& object, std::string key) {
@ -51,3 +54,5 @@ const boost::json::string& json_t::get_string(const boost::json::value& value) {
const boost::json::string& json_t::get_string(const boost::json::object& object, std::string key) {
return get_string(get_value(object, key));
}
#endif

@ -1,11 +1,13 @@
#pragma once
#include <cstdint>
#include <string>
#include <boost/json.hpp>
#ifdef USE_BOOST_JSON
# include <cstdint>
# include <string>
# include <boost/json.hpp>
#endif
class json_t {
#ifdef USE_BOOST_JSON
protected:
[[nodiscard]] static const boost::json::value& get_value(const boost::json::object& object, std::string key);
@ -22,4 +24,5 @@ protected:
[[nodiscard]] static const boost::json::string& get_string(const boost::json::value& value);
[[nodiscard]] static const boost::json::string& get_string(const boost::json::object& object, std::string key);
#endif
};

@ -16,6 +16,8 @@ std::string opcode_test_suite_t::read(std::string path) {
opcode_test_suite_t::opcode_test_suite_t(std::string path)
: m_path(path) {}
#ifdef USE_BOOST_JSON
const boost::json::array& opcode_test_suite_t::get_array() const noexcept {
assert(raw().is_array());
return raw().get_array();
@ -25,3 +27,14 @@ void opcode_test_suite_t::load() {
const auto contents = read(path());
m_raw = boost::json::parse(contents);
}
#endif
#ifdef USE_NLOHMANN_JSON
void opcode_test_suite_t::load() {
const auto contents = read(path());
m_raw = nlohmann::json::parse(contents);
}
#endif

@ -1,21 +1,36 @@
#pragma once
#include <string>
#include <boost/json.hpp>
#ifdef USE_BOOST_JSON
# include <boost/json.hpp>
#endif
#ifdef USE_NLOHMANN_JSON
# include "nlohmann/json.hpp"
#endif
class opcode_test_suite_t final {
private:
[[nodiscard]] static std::string read(std::string path);
std::string m_path;
#ifdef USE_BOOST_JSON
boost::json::value m_raw;
#endif
#ifdef USE_NLOHMANN_JSON
nlohmann::json m_raw;
#endif
public:
opcode_test_suite_t(std::string path);
[[nodiscard]] constexpr const auto& path() const noexcept { return m_path; }
[[nodiscard]] constexpr const auto& raw() const noexcept { return m_raw; }
#ifdef USE_BOOST_JSON
[[nodiscard]] const boost::json::array& get_array() const noexcept;
#endif
void load();
};

@ -2,6 +2,21 @@
#include "state_t.h"
#include <cassert>
state_t::state_t() {}
#ifdef USE_BOOST_JSON
state_t::state_t(const boost::json::object& serialised) {
initialise(serialised);
assert(initialised());
}
state_t::state_t(const boost::json::value& serialised) {
assert(serialised.is_object());
initialise(serialised.get_object());
assert(initialised());
}
void state_t::initialise(const boost::json::object& serialised) {
assert(!initialised());
@ -26,15 +41,38 @@ void state_t::initialise(const boost::json::object& serialised) {
m_initialised = true;
}
state_t::state_t() {}
#endif
state_t::state_t(const boost::json::object& serialised) {
#ifdef USE_NLOHMANN_JSON
state_t::state_t(const nlohmann::json& serialised) {
assert(serialised.is_object());
initialise(serialised);
assert(initialised());
}
state_t::state_t(const boost::json::value& serialised) {
assert(serialised.is_object());
initialise(serialised.get_object());
assert(initialised());
void state_t::initialise(const nlohmann::json& serialised) {
assert(!initialised());
m_pc = serialised["pc"].get<uint16_t>();
m_s = serialised["s"].get<uint8_t>();
m_a = serialised["a"].get<uint8_t>();
m_x = serialised["x"].get<uint8_t>();
m_y = serialised["y"].get<uint8_t>();
m_p = serialised["p"].get<uint8_t>();
const auto& ram_entries = serialised["ram"];
assert(ram_entries.is_array());
for (const auto& ram_entry : ram_entries) {
assert(ram_entry.is_array());
assert(ram_entry.size() == 2);
const auto address = ram_entry[0].get<uint16_t>();
const auto value = ram_entry[1].get<uint8_t>();
m_ram[address] = value;
}
m_initialised = true;
}
#endif

@ -2,7 +2,14 @@
#include <cstdint>
#include <unordered_map>
#include <boost/json.hpp>
#ifdef USE_BOOST_JSON
# include <boost/json.hpp>
#endif
#ifdef USE_NLOHMANN_JSON
# include "nlohmann/json.hpp"
#endif
#include "json_t.h"
@ -20,12 +27,25 @@ private:
[[nodiscard]] constexpr auto initialised() const noexcept { return m_initialised; }
#ifdef USE_BOOST_JSON
void initialise(const boost::json::object& serialised);
#endif
#ifdef USE_NLOHMANN_JSON
void initialise(const nlohmann::json& serialised);
#endif
public:
state_t();
#ifdef USE_BOOST_JSON
state_t(const boost::json::object& serialised);
state_t(const boost::json::value& serialised);
#endif
#ifdef USE_NLOHMANN_JSON
state_t(const nlohmann::json& serialised);
#endif
[[nodiscard]] constexpr auto pc() const noexcept { return m_pc; }
[[nodiscard]] constexpr auto s() const noexcept { return m_s; }

@ -11,4 +11,13 @@
#include <unordered_map>
#include <vector>
#include <boost/json.hpp>
//#define USE_BOOST_JSON
#define USE_NLOHMANN_JSON
#ifdef USE_BOOST_JSON
# include <boost/json.hpp>
#endif
#ifdef USE_NLOHMANN_JSON
# include "nlohmann/json.hpp"
#endif

@ -19,6 +19,17 @@ std::string test_t::to_string(action value) {
throw new std::out_of_range("Unknown action");
}
#ifdef USE_BOOST_JSON
test_t::test_t(const boost::json::object& serialised) {
initialise(serialised);
}
test_t::test_t(const boost::json::value& serialised) {
assert(serialised.is_object());
initialise(serialised.get_object());
}
void test_t::initialise(const boost::json::object& serialised) {
m_name = get_string(serialised, "name");
@ -34,15 +45,35 @@ void test_t::initialise(const boost::json::object& serialised) {
const auto address = get_uint16(cycle_array[0]);
const auto contents = get_uint8(cycle_array[1]);
const auto action = to_action((std::string)get_string(cycle_array[2]));
m_cycles.push_back( { address, contents, action } );
m_cycles.push_back({ address, contents, action });
}
}
test_t::test_t(const boost::json::object& serialised) {
#endif
#ifdef USE_NLOHMANN_JSON
test_t::test_t(const nlohmann::json& serialised) {
assert(serialised.is_object());
initialise(serialised);
}
test_t::test_t(const boost::json::value& serialised) {
assert(serialised.is_object());
initialise(serialised.get_object());
void test_t::initialise(const nlohmann::json& serialised) {
m_name = serialised["name"].get<std::string>();
m_initial_state = state_t(serialised["initial"]);
m_final_state = state_t(serialised["final"]);
const auto& cycles_array = serialised["cycles"];
m_cycles.reserve(cycles_array.size());
for (const auto& cycles_entry : cycles_array) {
assert(cycles_entry.size() == 3);
const auto address = cycles_entry[0].get<uint16_t>();
const auto contents = cycles_entry[1].get<uint8_t>();
const auto action = to_action(cycles_entry[2].get<std::string>());
m_cycles.push_back({ address, contents, action });
}
}
#endif

@ -4,7 +4,14 @@
#include <string>
#include <vector>
#include <tuple>
#include <boost/json.hpp>
#ifdef USE_BOOST_JSON
# include <boost/json.hpp>
#endif
#ifdef USE_NLOHMANN_JSON
# include "nlohmann/json.hpp"
#endif
#include "state_t.h"
#include "json_t.h"
@ -25,11 +32,24 @@ private:
state_t m_final_state;
events_t m_cycles;
#ifdef USE_BOOST_JSON
void initialise(const boost::json::object& serialised);
#endif
#ifdef USE_NLOHMANN_JSON
void initialise(const nlohmann::json& serialised);
#endif
public:
#ifdef USE_BOOST_JSON
test_t(const boost::json::object& serialised);
test_t(const boost::json::value& serialised);
#endif
#ifdef USE_NLOHMANN_JSON
test_t(const nlohmann::json& serialised);
#endif
[[nodiscard]] constexpr const auto& name() const noexcept { return m_name; }
[[nodiscard]] constexpr const auto& initial_state() const noexcept { return m_initial_state; }

@ -1,5 +1,6 @@
#include "stdafx.h"
#include <chrono>
#include <iostream>
#include <filesystem>
@ -11,6 +12,8 @@ int main() {
std::filesystem::path location = "C:\\github\\spectrum\\libraries\\EightBit\\modules\\ProcessorTests\\6502\\v1";
const auto start_time = std::chrono::steady_clock::now();
for (const auto& entry : std::filesystem::directory_iterator{ location }) {
const auto path = entry.path();
@ -20,7 +23,13 @@ int main() {
opcode_test_suite_t opcode(path.string());
opcode.load();
#ifdef USE_BOOST_JSON
const auto& opcode_test_array = opcode.get_array();
#endif
#ifdef USE_NLOHMANN_JSON
const auto& opcode_test_array = opcode.raw();
#endif
bool opcode_bad = false;
for (const auto& opcode_test_element : opcode_test_array) {
@ -39,4 +48,12 @@ int main() {
}
}
}
const auto finish_time = std::chrono::steady_clock::now();
const auto elapsed_time = finish_time - start_time;
const auto seconds = std::chrono::duration_cast<std::chrono::duration<double>>(elapsed_time).count();
std::cout << "Elapsed time: " << seconds << " seconds" << std::endl;
}