312 lines
11 KiB
C++
312 lines
11 KiB
C++
#include "commit_request.hpp"
|
|
#include "test_data.hpp"
|
|
|
|
#include <iostream>
|
|
#include <nanobench.h>
|
|
#include <nlohmann/json.hpp>
|
|
#include <string>
|
|
|
|
using namespace weaseldb::test_data;
|
|
|
|
// JSON test data is now provided by test_data.hpp
|
|
|
|
// Helper function to simulate validation work on nlohmann json object
|
|
bool validate_nlohmann_commit_request(const nlohmann::json &j) {
|
|
try {
|
|
// Basic structure validation
|
|
if (!j.is_object())
|
|
return false;
|
|
|
|
// Check required fields
|
|
if (j.contains("read_version") && !j["read_version"].is_number())
|
|
return false;
|
|
if (j.contains("leader_id") && !j["leader_id"].is_string())
|
|
return false;
|
|
if (j.contains("request_id") && !j["request_id"].is_string())
|
|
return false;
|
|
|
|
// Validate preconditions array
|
|
if (j.contains("preconditions")) {
|
|
if (!j["preconditions"].is_array())
|
|
return false;
|
|
for (const auto &precond : j["preconditions"]) {
|
|
if (!precond.is_object())
|
|
return false;
|
|
if (!precond.contains("type") || !precond["type"].is_string())
|
|
return false;
|
|
if (!precond.contains("version") || !precond["version"].is_number())
|
|
return false;
|
|
|
|
std::string type = precond["type"];
|
|
if (type == "point_read") {
|
|
if (!precond.contains("key") || !precond["key"].is_string())
|
|
return false;
|
|
} else if (type == "range_read") {
|
|
if (!precond.contains("begin") || !precond["begin"].is_string())
|
|
return false;
|
|
if (!precond.contains("end") || !precond["end"].is_string())
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Validate operations array
|
|
if (j.contains("operations")) {
|
|
if (!j["operations"].is_array())
|
|
return false;
|
|
for (const auto &op : j["operations"]) {
|
|
if (!op.is_object())
|
|
return false;
|
|
if (!op.contains("type") || !op["type"].is_string())
|
|
return false;
|
|
|
|
std::string type = op["type"];
|
|
if (type == "write") {
|
|
if (!op.contains("key") || !op["key"].is_string())
|
|
return false;
|
|
if (!op.contains("value") || !op["value"].is_string())
|
|
return false;
|
|
} else if (type == "delete") {
|
|
if (!op.contains("key") || !op["key"].is_string())
|
|
return false;
|
|
} else if (type == "range_delete") {
|
|
if (!op.contains("begin") || !op["begin"].is_string())
|
|
return false;
|
|
if (!op.contains("end") || !op["end"].is_string())
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
} catch (const std::exception &) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
std::cout << "Parser Comparison Benchmarks\n";
|
|
std::cout << "=============================\n\n";
|
|
|
|
// Simple JSON comparison
|
|
auto simple_bench = ankerl::nanobench::Bench()
|
|
.title("Simple JSON Parsing Comparison")
|
|
.unit("parse")
|
|
.warmup(100)
|
|
.minEpochIterations(1000);
|
|
|
|
simple_bench.run("WeaselDB Parser", [&] {
|
|
CommitRequest request;
|
|
std::string mutable_json = SIMPLE_JSON;
|
|
bool result = request.parse_json(mutable_json.data(), mutable_json.size());
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(request.is_parse_complete());
|
|
});
|
|
|
|
simple_bench.run("nlohmann/json + validation", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(SIMPLE_JSON);
|
|
bool result = validate_nlohmann_commit_request(j);
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
simple_bench.run("nlohmann/json (parse only)", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(SIMPLE_JSON);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
// Medium complexity JSON comparison
|
|
auto medium_bench = ankerl::nanobench::Bench()
|
|
.title("Medium JSON Parsing Comparison")
|
|
.unit("parse")
|
|
.warmup(100)
|
|
.minEpochIterations(500);
|
|
|
|
medium_bench.run("WeaselDB Parser", [&] {
|
|
CommitRequest request;
|
|
std::string mutable_json = MEDIUM_JSON;
|
|
bool result = request.parse_json(mutable_json.data(), mutable_json.size());
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(request.is_parse_complete());
|
|
});
|
|
|
|
medium_bench.run("nlohmann/json + validation", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(MEDIUM_JSON);
|
|
bool result = validate_nlohmann_commit_request(j);
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
medium_bench.run("nlohmann/json (parse only)", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(MEDIUM_JSON);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
// Complex JSON comparison
|
|
auto complex_bench = ankerl::nanobench::Bench()
|
|
.title("Complex JSON Parsing Comparison")
|
|
.unit("parse")
|
|
.warmup(100)
|
|
.minEpochIterations(200);
|
|
|
|
complex_bench.run("WeaselDB Parser", [&] {
|
|
CommitRequest request;
|
|
std::string mutable_json = COMPLEX_JSON;
|
|
bool result = request.parse_json(mutable_json.data(), mutable_json.size());
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(request.is_parse_complete());
|
|
});
|
|
|
|
complex_bench.run("nlohmann/json + validation", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(COMPLEX_JSON);
|
|
bool result = validate_nlohmann_commit_request(j);
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
complex_bench.run("nlohmann/json (parse only)", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(COMPLEX_JSON);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
// Large batch operations comparison
|
|
auto large_bench = ankerl::nanobench::Bench()
|
|
.title("Large JSON Parsing Comparison")
|
|
.unit("parse")
|
|
.warmup(50)
|
|
.minEpochIterations(100);
|
|
|
|
for (int num_ops : {50, 100, 500}) {
|
|
std::string large_json = generate_large_json(num_ops);
|
|
std::string bench_name = std::to_string(num_ops) + " operations";
|
|
|
|
large_bench.run("WeaselDB Parser (" + bench_name + ")", [&] {
|
|
CommitRequest request;
|
|
std::string mutable_json = large_json;
|
|
bool result =
|
|
request.parse_json(mutable_json.data(), mutable_json.size());
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(request.is_parse_complete());
|
|
});
|
|
|
|
large_bench.run("nlohmann/json + validation (" + bench_name + ")", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(large_json);
|
|
bool result = validate_nlohmann_commit_request(j);
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
large_bench.run("nlohmann/json (parse only) (" + bench_name + ")", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(large_json);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Memory efficiency comparison
|
|
auto memory_bench = ankerl::nanobench::Bench()
|
|
.title("Memory Efficiency Comparison")
|
|
.unit("allocation")
|
|
.warmup(50)
|
|
.minEpochIterations(200);
|
|
|
|
memory_bench.run("WeaselDB Parser (arena allocation)", [&] {
|
|
CommitRequest request(4096); // 4KB arena
|
|
std::string mutable_json = COMPLEX_JSON;
|
|
bool result = request.parse_json(mutable_json.data(), mutable_json.size());
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(request.total_allocated());
|
|
ankerl::nanobench::doNotOptimizeAway(request.used_bytes());
|
|
});
|
|
|
|
memory_bench.run("nlohmann/json (standard allocation)", [&] {
|
|
try {
|
|
nlohmann::json j = nlohmann::json::parse(COMPLEX_JSON);
|
|
bool result = validate_nlohmann_commit_request(j);
|
|
ankerl::nanobench::doNotOptimizeAway(result);
|
|
ankerl::nanobench::doNotOptimizeAway(j.size());
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
// Reset and reuse comparison
|
|
auto reuse_bench = ankerl::nanobench::Bench()
|
|
.title("Reset and Reuse Comparison")
|
|
.unit("cycle")
|
|
.warmup(50)
|
|
.minEpochIterations(100);
|
|
|
|
reuse_bench.run("WeaselDB Parser (reset)", [&] {
|
|
static CommitRequest request;
|
|
|
|
std::string mutable_json1 = SIMPLE_JSON;
|
|
bool result1 =
|
|
request.parse_json(mutable_json1.data(), mutable_json1.size());
|
|
|
|
request.reset();
|
|
|
|
std::string mutable_json2 = MEDIUM_JSON;
|
|
bool result2 =
|
|
request.parse_json(mutable_json2.data(), mutable_json2.size());
|
|
|
|
ankerl::nanobench::doNotOptimizeAway(result1);
|
|
ankerl::nanobench::doNotOptimizeAway(result2);
|
|
});
|
|
|
|
reuse_bench.run("nlohmann/json (new instance)", [&] {
|
|
try {
|
|
nlohmann::json j1 = nlohmann::json::parse(SIMPLE_JSON);
|
|
bool result1 = validate_nlohmann_commit_request(j1);
|
|
|
|
nlohmann::json j2 = nlohmann::json::parse(MEDIUM_JSON);
|
|
bool result2 = validate_nlohmann_commit_request(j2);
|
|
|
|
ankerl::nanobench::doNotOptimizeAway(result1);
|
|
ankerl::nanobench::doNotOptimizeAway(result2);
|
|
} catch (const std::exception &) {
|
|
ankerl::nanobench::doNotOptimizeAway(false);
|
|
}
|
|
});
|
|
|
|
std::cout << "\nBenchmark completed. The WeaselDB parser is optimized for:\n";
|
|
std::cout << "- Arena-based memory allocation for reduced fragmentation\n";
|
|
std::cout << "- Streaming parsing for network protocols\n";
|
|
std::cout << "- Zero-copy string handling with string views\n";
|
|
std::cout << "- Base64 decoding integrated into parsing pipeline\n";
|
|
std::cout << "- Efficient reset and reuse for high-throughput scenarios\n";
|
|
|
|
return 0;
|
|
}
|