-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbenchmark_runner.cpp
More file actions
163 lines (142 loc) · 5.86 KB
/
benchmark_runner.cpp
File metadata and controls
163 lines (142 loc) · 5.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "Tachyon.hpp"
#include "simdjson.h"
#include <glaze/glaze.hpp>
#include <chrono>
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <numeric>
#include <algorithm>
#include <sched.h>
#include <fstream>
#include <cstring>
// Zapobiega "wycinaniu" kodu
template <typename T>
void do_not_optimize(const T& val) {
asm volatile("" : : "g"(&val) : "memory");
}
void pin_to_core(int core_id) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
}
std::string read_file(const std::string& path) {
std::ifstream f(path, std::ios::binary | std::ios::ate);
if (!f) return "";
auto size = f.tellg();
f.seekg(0);
std::string s;
s.resize(size);
f.read(&s[0], size);
s.append(128, ' ');
return s;
}
struct Stats {
double mb_s;
double median_time;
};
Stats calculate_stats(std::vector<double>& times, size_t bytes) {
std::sort(times.begin(), times.end());
double median = times[times.size() / 2];
double mb_s = (bytes / 1024.0 / 1024.0) / median;
return { mb_s, median };
}
int main() {
pin_to_core(0);
std::string canada_data = read_file("canada.json");
std::string huge_data = read_file("huge.json");
if (canada_data.empty() || huge_data.empty()) {
std::cerr << "BŁĄD: Pliki JSON nie zostały znalezione!" << std::endl;
return 1;
}
struct Job { std::string name; const char* ptr; size_t size; };
std::vector<Job> jobs = {
{"Canada", canada_data.data(), canada_data.size() - 128},
{"Huge (256MB)", huge_data.data(), huge_data.size() - 128}
};
std::cout << "==========================================================" << std::endl;
std::cout << "[PROTOKÓŁ: ZERO BIAS - ULTRA PRECISION TEST]" << std::endl;
std::cout << "[ISA: " << Tachyon::get_isa_name() << " | ITERS: 50 | WARMUP: 20]" << std::endl;
std::cout << "==========================================================" << std::endl;
std::cout << std::fixed << std::setprecision(12);
for (const auto& job : jobs) {
const int iters = 50;
const int warmup = 20;
std::cout << "\n>>> Dataset: " << job.name << " (" << job.size << " bytes)" << std::endl;
std::cout << "| Library | Speed (MB/s) | Median Time (s) |" << std::endl;
std::cout << "|---|---|---|" << std::endl;
// --- 1. SIMDJSON (IDZIE PIERWSZY) ---
{
simdjson::ondemand::parser parser;
simdjson::padded_string_view p_view(job.ptr, job.size, job.size + 64);
std::vector<double> times;
// Rozgrzewka Cache
for(int i = 0; i < warmup; ++i) {
auto doc = parser.iterate(p_view);
if (job.name.find("Huge") != std::string::npos) {
for (auto val : doc.get_array()) { do_not_optimize(val); }
} else { do_not_optimize(doc["type"]); }
}
// Pomiar
for (int i = 0; i < iters; ++i) {
auto start = std::chrono::high_resolution_clock::now();
auto doc = parser.iterate(p_view);
if (job.name.find("Huge") != std::string::npos) {
for (auto val : doc.get_array()) { do_not_optimize(val); }
} else { do_not_optimize(doc["type"]); }
auto end = std::chrono::high_resolution_clock::now();
times.push_back(std::chrono::duration<double>(end - start).count());
}
auto s = calculate_stats(times, job.size);
std::cout << "| Simdjson (Fair) | " << std::setw(12) << std::setprecision(2) << s.mb_s
<< " | " << std::setprecision(12) << s.median_time << " |" << std::endl;
}
// --- 2. TACHYON (IDZIE DRUGI) ---
{
Tachyon::Context ctx;
std::vector<double> times;
// Rozgrzewka Cache
for(int i = 0; i < warmup; ++i) {
Tachyon::json doc = ctx.parse_view(job.ptr, job.size);
if (doc.is_array()) do_not_optimize(doc.size());
else do_not_optimize(doc.contains("type"));
}
// Pomiar
for (int i = 0; i < iters; ++i) {
auto start = std::chrono::high_resolution_clock::now();
Tachyon::json doc = ctx.parse_view(job.ptr, job.size);
if (doc.is_array()) do_not_optimize(doc.size());
else do_not_optimize(doc.contains("type"));
auto end = std::chrono::high_resolution_clock::now();
times.push_back(std::chrono::duration<double>(end - start).count());
}
auto s = calculate_stats(times, job.size);
std::cout << "| Tachyon (Turbo) | " << std::setw(12) << std::setprecision(2) << s.mb_s
<< " | " << std::setprecision(12) << s.median_time << " |" << std::endl;
}
// --- 3. GLAZE ---
{
std::vector<double> times;
glz::generic v;
// Rozgrzewka
for(int i = 0; i < warmup; ++i) {
std::string_view sv(job.ptr, job.size);
glz::read_json(v, sv);
}
// Pomiar
for (int i = 0; i < iters; ++i) {
auto start = std::chrono::high_resolution_clock::now();
std::string_view sv(job.ptr, job.size);
glz::read_json(v, sv);
auto end = std::chrono::high_resolution_clock::now();
times.push_back(std::chrono::duration<double>(end - start).count());
}
auto s = calculate_stats(times, job.size);
std::cout << "| Glaze (Reuse) | " << std::setprecision(2) << s.mb_s
<< " | " << std::setprecision(12) << s.median_time << " |" << std::endl;
}
}
return 0;
}