Skip to content

Commit 7179443

Browse files
authored
Write gcperfsim result in json (#4651)
* Generate json for gcperfsim and gcperfsim-compare commands * clean the code * restore global.json
1 parent b2126cd commit 7179443

File tree

3 files changed

+145
-1
lines changed

3 files changed

+145
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using GC.Analysis.API;
2+
using GC.Infrastructure.Core.Analysis;
3+
using GC.Infrastructure.Core.Configurations.GCPerfSim;
4+
using Newtonsoft.Json;
5+
using System.Collections.Concurrent;
6+
7+
namespace GC.Infrastructure.Core.Presentation.GCPerfSim
8+
{
9+
public static class Json
10+
{
11+
private static readonly Dictionary<string, Func<ComparisonResult, bool>> diffLevelPredicate = new() {
12+
{ "LargeRegressions", c => c.PercentageDelta > 20 },
13+
{ "LargeImprovements", c => c.PercentageDelta < -20 },
14+
{ "Regressions", c => c.PercentageDelta > 5 && c.PercentageDelta < 20 },
15+
{ "Improvements", c => c.PercentageDelta < -5 && c.PercentageDelta > -20 },
16+
{ "StaleRegressions", c => c.PercentageDelta >= 0 && c.PercentageDelta < 5 },
17+
{ "StaleImprovements", c => c.PercentageDelta < 0 && c.PercentageDelta > -5 },
18+
};
19+
20+
public static void GenerateComparisonDictionary(ResultItem baseResultItem, ResultItem comparandResultItem, string path)
21+
{
22+
Dictionary<string, List<ComparisonResult>> comparisonResultsJson = new();
23+
List<ComparisonResult> comparisonResults = new();
24+
25+
var resultItemComparison = new ResultItemComparison(baseResultItem, comparandResultItem);
26+
foreach (var property in typeof(ResultItem).GetProperties())
27+
{
28+
if (property.PropertyType != typeof(double))
29+
{
30+
continue;
31+
}
32+
33+
string propertyNameToCheck = property.Name.ToLowerInvariant();
34+
35+
ComparisonResult result = resultItemComparison.GetComparison(property.Name);
36+
comparisonResults.Add(result);
37+
}
38+
39+
foreach (var item in diffLevelPredicate)
40+
{
41+
string key = item.Key;
42+
Func<ComparisonResult, bool> predicate = item.Value;
43+
comparisonResultsJson[key] = comparisonResultsJson.GetValueOrDefault(key, new List<ComparisonResult>());
44+
GoodLinq
45+
.Where(comparisonResults, predicate)
46+
.ForEach(r => comparisonResultsJson[key].Add(r));
47+
}
48+
49+
string json = JsonConvert.SerializeObject(comparisonResultsJson);
50+
File.WriteAllText(path, json);
51+
}
52+
53+
public static void GenerateDictionary(GCPerfSimConfiguration configuration, Dictionary<string, ProcessExecutionDetails> executionDetails, string path)
54+
{
55+
string GetExecutionDetailKey(string runName, string corerunName) => $"{runName}.{corerunName}.0";
56+
string baseCoreRun = configuration.coreruns.First().Key;
57+
58+
ConcurrentDictionary<string, ConcurrentDictionary<string, ResultItem>> runToCorerunData = AnalyzeTrace.GetTracesFromConfiguration(configuration);
59+
60+
Dictionary<string, Dictionary<string, List<ComparisonResult>>> allComparisonResultsJson = new();
61+
foreach (var run in configuration.Runs)
62+
{
63+
allComparisonResultsJson[run.Key] = allComparisonResultsJson.GetValueOrDefault(run.Key, new());
64+
// Baseline.
65+
string baseExecutionItem = GetExecutionDetailKey(run.Key, baseCoreRun);
66+
67+
ResultItem baseRunItem = runToCorerunData.TryGetResultItemFromDictionary(run.Key, baseCoreRun); // [run.Key][baseCoreRun];
68+
69+
List<ComparisonResult> comparisonResults = new();
70+
71+
foreach (var corerun in configuration.coreruns)
72+
{
73+
if (corerun.Key == baseCoreRun)
74+
{
75+
continue;
76+
}
77+
78+
string runKey = GetExecutionDetailKey(run.Key, corerun.Key);
79+
80+
ResultItem comparandRunItem = runToCorerunData.TryGetResultItemFromDictionary(run.Key, corerun.Key);
81+
var resultItemComparison = new ResultItemComparison(baseRunItem, comparandRunItem);
82+
83+
HashSet<string> requestedPropertyNames = new HashSet<string>(GoodLinq.Select(configuration.Output.Columns, (c => c.ToLowerInvariant().Replace(" ", "").Replace("(", ")").Replace(")", ""))));
84+
85+
foreach (var property in typeof(ResultItem).GetProperties())
86+
{
87+
if (property.PropertyType != typeof(double))
88+
{
89+
continue;
90+
}
91+
92+
string propertyNameToCheck = property.Name.ToLowerInvariant();
93+
94+
ComparisonResult result = resultItemComparison.GetComparison(property.Name);
95+
comparisonResults.Add(result);
96+
}
97+
}
98+
99+
Dictionary<string, List<ComparisonResult>> comparisonResultsJson = new();
100+
101+
foreach (var item in diffLevelPredicate)
102+
{
103+
string key = item.Key;
104+
Func<ComparisonResult, bool> predicate = item.Value;
105+
comparisonResultsJson[key] = comparisonResultsJson.GetValueOrDefault(key, new List<ComparisonResult>());
106+
GoodLinq
107+
.Where(comparisonResults, predicate)
108+
.ForEach(r => comparisonResultsJson[key].Add(r));
109+
}
110+
111+
allComparisonResultsJson[run.Key] = comparisonResultsJson;
112+
}
113+
114+
string json = JsonConvert.SerializeObject(allComparisonResultsJson);
115+
File.WriteAllText(path, json);
116+
}
117+
118+
private static ResultItem TryGetResultItemFromDictionary(this ConcurrentDictionary<string, ConcurrentDictionary<string, ResultItem>> cache, string run, string corerun)
119+
{
120+
if (cache.TryGetValue(run, out var r) && r.TryGetValue(corerun, out var result))
121+
{
122+
return result;
123+
}
124+
125+
else
126+
{
127+
return ResultItem.GetNullItem(run, corerun);
128+
}
129+
}
130+
}
131+
}

src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure/Commands/GCPerfSim/GCPerfSimAnalyzeCommand.cs

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ public static IReadOnlyList<ComparisonResult> ExecuteAnalysis(GCPerfSimConfigura
3838
string outputPath = Path.Combine(configuration.Output!.Path, "Results.md");
3939
IReadOnlyList<ComparisonResult> results = Markdown.GenerateTable(configuration, executionDetails, outputPath);
4040
AnsiConsole.MarkupLine($"[green bold] ({DateTime.Now}) Results written to {outputPath} [/]");
41+
if (configuration.Output.Formats.Contains("json"))
42+
{
43+
outputPath = Path.Combine(configuration.Output!.Path, "Results.json");
44+
Json.GenerateDictionary(configuration, executionDetails, outputPath);
45+
AnsiConsole.MarkupLine($"[green bold] ({DateTime.Now}) Results written to {outputPath} [/]");
46+
}
4147
return results;
4248
}
4349
}

src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure/Commands/GCPerfSim/GCPerfSimCompare.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,14 @@ public override int Execute([NotNull] CommandContext context, [NotNull] GCPerfSi
4343
ResultItem baseline = comparisons.First().Value.Baseline;
4444
ResultItem run = comparisons.First().Value.Comparand;
4545

46-
Markdown.GenerateComparisonTable(baseline, run, settings.OutputPath);
46+
if (Path.GetExtension(settings.OutputPath) == ".json")
47+
{
48+
Json.GenerateComparisonDictionary(baseline, run, settings.OutputPath);
49+
}
50+
else
51+
{
52+
Markdown.GenerateComparisonTable(baseline, run, settings.OutputPath);
53+
}
4754
AnsiConsole.MarkupLine($"[green bold] ({DateTime.Now}) Results written to {settings.OutputPath} [/]");
4855
return 0;
4956
}

0 commit comments

Comments
 (0)