75 lines
2.8 KiB
C#
75 lines
2.8 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text.Encodings.Web;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using ParadoxSaveParser.Lib;
|
|
|
|
namespace ParadoxSaveParser.Benchmarks;
|
|
|
|
/// <summary>
|
|
/// Locates and lazily loads the benchmark corpus:
|
|
/// a real EU4 <c>gamestate</c> file and its compact JSON twin (for jq).
|
|
/// Override the directory with the PSP_BENCH_DATA environment variable.
|
|
/// </summary>
|
|
public static class BenchData
|
|
{
|
|
public const string PdxQuery = "countries.*.technology";
|
|
|
|
/// <summary>jq program extracting the same data as <see cref="PdxQuery" />.</summary>
|
|
public const string JqQuery = ".countries | map_values(.technology)";
|
|
|
|
public static string Dir { get; } =
|
|
Environment.GetEnvironmentVariable("PSP_BENCH_DATA")
|
|
?? Path.Combine(FindRepoRoot(), "ParadoxSaveParser.CLI", "bin", "Debug", "net10.0");
|
|
|
|
public static string PdxPath => Path.Combine(Dir, "gamestate");
|
|
public static string JsonPath => Path.Combine(Dir, "gamestate.min.json");
|
|
|
|
private static byte[]? _pdxBytes;
|
|
private static string? _pdxText;
|
|
|
|
/// <summary>Raw bytes of the save, kept in memory so benchmarks don't measure disk I/O.</summary>
|
|
public static byte[] PdxBytes => _pdxBytes ??= File.ReadAllBytes(PdxPath);
|
|
|
|
/// <summary>
|
|
/// The save decoded as text for the regex engines.
|
|
/// </summary>
|
|
public static string PdxText => _pdxText ??= SaveParserEU4.DefaultEncoding.GetString(PdxBytes);
|
|
|
|
private static string FindRepoRoot()
|
|
{
|
|
var dir = new DirectoryInfo(AppContext.BaseDirectory);
|
|
while (dir != null && !File.Exists(Path.Combine(dir.FullName, "ParadoxSaveParser.sln")))
|
|
dir = dir.Parent;
|
|
return dir?.FullName ?? Directory.GetCurrentDirectory();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Produces the compact JSON twin of the save file, which is what jq is given.
|
|
/// Compact (not indented) so jq isn't penalized by parsing whitespace.
|
|
/// </summary>
|
|
public static void PrepareJson()
|
|
{
|
|
if (File.Exists(JsonPath))
|
|
{
|
|
Console.WriteLine($"{JsonPath} already exists, skipping");
|
|
return;
|
|
}
|
|
|
|
Console.WriteLine($"parsing {PdxPath} ...");
|
|
using var input = File.OpenRead(PdxPath);
|
|
var root = new SaveParserEU4(input, null).Parse();
|
|
Console.WriteLine($"serializing to {JsonPath} ...");
|
|
using var output = File.Create(JsonPath);
|
|
JsonSerializer.Serialize(output, root, new JsonSerializerOptions
|
|
{
|
|
WriteIndented = false,
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
|
MaxDepth = 1024,
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
|
});
|
|
Console.WriteLine($"done: {new FileInfo(JsonPath).Length / 1024 / 1024} MB");
|
|
}
|
|
}
|