JsonParserByLeo/Test/Ben/Ben.mq5

376 lines
15 KiB
MQL5
Raw Permalink Normal View History

2026-06-28 18:47:50 -05:00
//+------------------------------------------------------------------+
//| Ben.mq5 |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com/"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "..\\..\\Src\\JsonNode.mqh"
#include "..\\..\\..\\fast_json\\fast_json.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#resource "twitter.json" as const string g_json_data
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
TSN::CJsonParser parser;
// Only one copy
parser.Assing(g_json_data);
2026-07-12 18:24:34 -05:00
parser.CorrectPadingForSwar();
2026-06-28 18:47:50 -05:00
Sleep(500);
ulong a = GetMicrosecondCount();
for(int i = 0; i < 1000; i++)
{
parser.Parse();
}
ulong b = GetMicrosecondCount() - a;
Print("Time: ", b);
//---
CJson json;
// Only one copy
StringToCharArray(g_json_data, json.ctx.buffer);
Sleep(250);
a = GetMicrosecondCount();
for(int i = 0; i < 1000; i++)
{
json.ParseData();
}
b = GetMicrosecondCount() - a;
Print("Time: ", b);
/*
2026.06.26 17:40:33.533 Ben (BTCUSD,D1) Time: 665763
2026.06.26 17:40:35.093 Ben (BTCUSD,D1) Time: 1292446
2026.06.26 17:40:40.042 Ben (BTCUSD,D1) Time: 664394
2026.06.26 17:40:41.648 Ben (BTCUSD,D1) Time: 1345332
2026.06.26 17:40:45.973 Ben (BTCUSD,D1) Time: 666353
2026.06.26 17:40:47.522 Ben (BTCUSD,D1) Time: 1300799
2026.06.26 17:40:56.048 Ben (BTCUSD,D1) Time: 663639
2026.06.26 17:40:57.587 Ben (BTCUSD,D1) Time: 1292898
*/
}
//+------------------------------------------------------------------+
/*
import json
import timeit
import os
import simdjson
import orjson
import ujson
# ── Cargar el archivo una sola vez ──────────────────────────────────────────
FILE = "twitter.json"
assert os.path.exists(FILE), f"No se encontró {FILE}"
with open(FILE, "rb") as f:
raw_bytes = f.read()
raw_str = raw_bytes.decode("utf-8")
print(f"Archivo : {FILE}")
print(f"Tamaño : {len(raw_bytes) / 1024:.1f} KB")
print(f"Iters : 1000\n")
print(f"{'Librería':<22} {'Total (s)':>10} {'Por iter (ms)':>14} {'Speedup vs json':>16}")
print("" * 68)
ITERS = 1000
# ── stdlib json ──────────────────────────────────────────────────────────────
t_json = timeit.timeit(lambda: json.loads(raw_str), number=ITERS)
# ── orjson ───────────────────────────────────────────────────────────────────
t_orjson = timeit.timeit(lambda: orjson.loads(raw_bytes), number=ITERS)
# ── ujson ────────────────────────────────────────────────────────────────────
t_ujson = timeit.timeit(lambda: ujson.loads(raw_str), number=ITERS)
# ── simdjson.loads (drop-in) ─────────────────────────────────────────────────
t_simdjson_loads = timeit.timeit(lambda: simdjson.loads(raw_str), number=ITERS)
# ── simdjson Parser reutilizado ──────────────────────────────────────────────
parser = simdjson.Parser()
t_simdjson_parser = timeit.timeit(lambda: parser.parse(raw_bytes), number=ITERS)
# ── simdjson Parser + as_dict (convierte todo) ───────────────────────────────
t_simdjson_dict = timeit.timeit(
lambda: parser.parse(raw_bytes).as_dict(), number=ITERS
)
# ── Imprimir resultados ──────────────────────────────────────────────────────
results = [
("json (stdlib)", t_json),
("ujson", t_ujson),
("orjson", t_orjson),
("simdjson.loads", t_simdjson_loads),
("simdjson.Parser", t_simdjson_parser),
("simdjson.Parser+as_dict",t_simdjson_dict),
]
baseline = t_json
for name, t in results:
per_iter = (t / ITERS) * 1000
speedup = baseline / t
print(f"{name:<22} {t:>10.3f}s {per_iter:>13.2f}ms {speedup:>14.2f}x")
Archivo : twitter.json
Tamaño : 616.7 KB
Iters : 1000
Librería Total (s) Por iter (ms) Speedup vs json
json (stdlib) 5.860s 5.86ms 1.00x
ujson 5.322s 5.32ms 1.10x
orjson 1.863s 1.86ms 3.15x
simdjson.loads 4.955s 4.95ms 1.18x
simdjson.Parser 0.475s 0.47ms 12.34x
simdjson.Parser+as_dict 4.309s 4.31ms 1.36x
PS C:\Users\USER\Documents>
*/
/*
#include <iostream>
#include <chrono>
#include "simdjson.h" // o <simdjson.h> si usas vcpkg
#include "simdjson.cpp"
int main()
{
using clock = std::chrono::high_resolution_clock;
using ms = std::chrono::duration<double, std::milli>;
// ← PON AQUI LA RUTA A TU twitter.json
const char* JSON_PATH = R"(C:\Users\USER\Documents\te\twitter.json)";
constexpr int WARMUP = 20;
constexpr int ITERS = 1000;
// Cargar archivo
simdjson::padded_string json;
auto err = simdjson::padded_string::load(JSON_PATH).get(json);
if (err) {
std::cerr << "No se pudo abrir: " << JSON_PATH << "\n"
<< simdjson::error_message(err) << "\n";
return 1;
}
std::cout << "Archivo: " << json.size() / 1024 << " KB\n";
// Parser unico — se reutiliza en cada iteracion
simdjson::dom::parser parser;
// ── Warm-up ──────────────────────────────────────────
std::cout << "Warm-up (" << WARMUP << " iteraciones)...\n";
for (int i = 0; i < WARMUP; ++i) {
parser.parse(json);
}
// ── Benchmark ────────────────────────────────────────
std::cout << "Benchmark (" << ITERS << " iteraciones)...\n";
auto t0 = clock::now();
for (int i = 0; i < ITERS; ++i) {
parser.parse(json);
}
auto t1 = clock::now();
// ── Estadísticas ─────────────────────────────────────
double total_ms = ms(t1 - t0).count();
double mean_ms = total_ms / ITERS;
double file_mb = json.size() / (1024.0 * 1024.0);
double mean_mb_s = file_mb / (mean_ms / 1000.0);
std::cout << "\n────────────────────────────────────\n";
std::cout << " Archivo : " << json.size() / 1024 << " KB\n";
std::cout << " Iteraciones : " << ITERS << "\n";
std::cout << " Total : " << total_ms << " ms\n";
std::cout << " Media/iter : " << mean_ms << " ms\n";
std::cout << " Throughput : " << mean_mb_s << " MB/s\n";
std::cout << "────────────────────────────────────\n";
std::this_thread::sleep_for(std::chrono::seconds(10));
return 0;
}
//--- Result:
Archivo: 616 KB
Warm-up (20 iteraciones)...
Benchmark (1000 iteraciones)...
ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇ
Archivo : 616 KB
Iteraciones : 1000
Total : 381.131 ms
Media/iter : 0.381131 ms
Throughput : 1580.19 MB/s
ÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇÔöÇ
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define RYML_SINGLE_HDR_DEFINE_NOW
#include "yaml.hpp"
#include <chrono>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
#include <thread>
// ── Error handler ─────────────────────────────────────────────────────────────
struct YamlErrorHandler {
ryml::Callbacks original = ryml::get_callbacks();
ryml::Callbacks callbacks() {
ryml::Callbacks cb;
cb.set_error_parse([](ryml::csubstr msg, ryml::ErrorDataParse const& e, void*) {
throw std::runtime_error(
std::string(msg.str, msg.len) +
" [linea " + std::to_string(e.ymlloc.line) +
", col " + std::to_string(e.ymlloc.col) + "]"
);
});
cb.set_error_basic([](ryml::csubstr msg, ryml::ErrorDataBasic const&, void*) {
throw std::runtime_error(std::string(msg.str, msg.len));
});
return cb;
}
void install() { ryml::set_callbacks(callbacks()); }
void uninstall() { ryml::set_callbacks(original); }
};
// ── Leer archivo ──────────────────────────────────────────────────────────────
std::string read_file(const char* path) {
std::ifstream f(path);
if (!f.is_open()) { std::cerr << "No se pudo abrir: " << path << "\n"; exit(1); }
std::ostringstream ss;
ss << f.rdbuf();
return ss.str();
}
int main() {
const char* YAML_PATH = R"(C:\Users\USER\Documents\te\twitter.json)";
constexpr int WARMUP = 20;
constexpr int ITERS = 1000;
std::string content = read_file(YAML_PATH);
std::cout << "Archivo : " << YAML_PATH << "\n";
std::cout << "Tamanio : " << content.size() << " bytes ("
<< content.size() / 1024.0 << " KB)\n";
std::cout << "Iteraciones : " << ITERS << "\n\n";
// ── Buffer mutable ────────────────────────────────────────────────────────
// parse_in_place MUTA el buffer en cada llamada.
// Por eso se restaura desde 'content' antes de cada parse.
std::vector<char> buf(content.begin(), content.end());
buf.push_back('\0');
// ── Instalar error handler global ─────────────────────────────────────────
YamlErrorHandler errh;
errh.install();
// ── Parser y Tree reutilizados ────────────────────────────────────────────
ryml::EventHandlerTree handler;
ryml::Parser parser(&handler);
ryml::Tree tree;
// ── Warm-up ───────────────────────────────────────────────────────────────
std::cout << "Warm-up (" << WARMUP << " iteraciones)...\n";
try {
for (int i = 0; i < WARMUP; i++) {
std::copy(content.begin(), content.end(), buf.begin()); // restaurar buffer
ryml::substr yaml_src(buf.data(), content.size());
tree.clear();
ryml::parse_in_place(&parser, "test.yaml", yaml_src, &tree);
}
}
catch (const std::exception& e) {
std::cerr << "\nError en YAML:\n " << e.what() << "\n";
errh.uninstall();
return 1;
}
std::cout << "Warm-up OK\n\n";
// ── Benchmark ─────────────────────────────────────────────────────────────
std::cout << "Benchmark (" << ITERS << " iteraciones)...\n";
double ms_total = 0.0;
try {
for (int i = 0; i < ITERS; i++) {
std::copy(content.begin(), content.end(), buf.begin()); // restaurar buffer
ryml::substr yaml_src(buf.data(), content.size());
tree.clear();
auto t0 = std::chrono::high_resolution_clock::now();
ryml::parse_in_place(&parser, "test.yaml", yaml_src, &tree);
auto t1 = std::chrono::high_resolution_clock::now();
ms_total += std::chrono::duration<double, std::milli>(t1 - t0).count();
}
}
catch (const std::exception& e) {
std::cerr << "\nError en YAML:\n " << e.what() << "\n";
errh.uninstall();
return 1;
}
errh.uninstall();
// ── Resultados ────────────────────────────────────────────────────────────
double ms_iter = ms_total / ITERS;
double mb_s = (content.size() / 1024.0 / 1024.0) / (ms_total / 1000.0 / ITERS);
std::cout << "\n=== Resultados ===\n";
std::cout << "Total : " << ms_total << " ms\n";
std::cout << "Media/iter : " << ms_iter << " ms\n";
std::cout << "Throughput : " << mb_s << " MB/s\n";
std::this_thread::sleep_for(std::chrono::seconds(10));
return 0;
}
Archivo : C:\Users\USER\Documents\te\twitter.json
Tamanio : 631515 bytes (616.714 KB)
Iteraciones : 1000
Warm-up (20 iteraciones)...
Warm-up OK
Benchmark (1000 iteraciones)...
=== Resultados ===
Total : 2846.55 ms
Media/iter : 2.84655 ms
Throughput : 211.575 MB/s
*/
//+------------------------------------------------------------------+