using System.IO; using System.Text.RegularExpressions; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; using ParadoxSaveParser.Lib; using PCRE; namespace ParadoxSaveParser.Benchmarks; /// /// In-process engines, all extracting countries.*.technology from the same 110 MB save. /// Input is preloaded into memory, so disk I/O is not part of any measurement. /// [MemoryDiagnoser] [SimpleJob(RunStrategy.Monitoring, launchCount: 1, warmupCount: 1, iterationCount: 5)] public class ExtractionBenchmarks { private byte[] _pdx = null!; private string _pdxText = null!; private byte[] _json = null!; private SearchExpressionCompilation _query = null!; private Regex _technologyBlock = null!; private Regex _pathAwareCompiled = null!; private Regex _pathAwareNonBacktracking = null!; private Regex _countriesBlock = null!; private PcreRegex _pcrePathAware = null!; [GlobalSetup] public void Setup() { _pdx = BenchData.PdxBytes; _pdxText = BenchData.PdxText; _json = File.ReadAllBytes(BenchData.JsonPath); _query = new SearchExpressionCompilation(BenchData.PdxQuery); _technologyBlock = new Regex(Extractors.TechnologyBlockPattern, RegexOptions.Compiled); _pathAwareCompiled = new Regex(Extractors.PathAwarePattern, RegexOptions.Compiled); _pathAwareNonBacktracking = new Regex(Extractors.PathAwarePattern, RegexOptions.NonBacktracking); _countriesBlock = new Regex(Extractors.CountriesBlockPattern, RegexOptions.Compiled); _pcrePathAware = new PcreRegex(Extractors.PathAwarePattern, PcreOptions.Compiled); } [Benchmark(Baseline = true, Description = "SearchExpression (this project)")] public long SearchExpression() => Extractors.SearchExpression(_pdx, _query); [Benchmark(Description = "Full parse, then select")] public long FullParse() => Extractors.FullParseThenSelect(_pdx); [Benchmark(Description = ".NET Regex path aware, compiled")] public long RegexPathAwareCompiled() => Extractors.RegexScan(_pathAwareCompiled, _pdxText); [Benchmark(Description = ".NET Regex path aware, NonBacktracking")] public long RegexPathAwareNonBacktracking() => Extractors.RegexScan(_pathAwareNonBacktracking, _pdxText); [Benchmark(Description = ".NET Regex balanced block + inner scan")] public long RegexBalancedTwoStage() => Extractors.RegexTwoStage(_countriesBlock, _technologyBlock, _pdxText); [Benchmark(Description = "PCRE.NET path aware, JIT compiled")] public long PcrePathAware() => Extractors.PcreScan(_pcrePathAware, _pdxText); [Benchmark(Description = "Utf8JsonReader over JSON twin")] public long Utf8JsonReader() => Extractors.Utf8JsonReaderScan(_json); [Benchmark(Description = "JsonDocument over JSON twin")] public long JsonDocument() => Extractors.JsonDocumentScan(_json); }