Skip to content

Commit 361b054

Browse files
committed
improved export of model computation stats
1 parent 9833c89 commit 361b054

File tree

2 files changed

+38
-27
lines changed

2 files changed

+38
-27
lines changed

Commands/ModelComputationStatsCommand.cs

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,16 @@ await WrapExceptions(async () =>
6464
Identifier = ticketDecrypted.Model.Id;
6565
}
6666

67+
// keep a log of message and export it to a file
68+
var log = new StringBuilder();
69+
Action<string> logMessage = (string message) =>
70+
{
71+
Console.WriteLine(message);
72+
log.AppendLine(message);
73+
};
74+
6775
// get model call
68-
Console.WriteLine($"Get model information...");
76+
logMessage($"Get model information for identifier {Identifier} ...");
6977
var model = (await sdk.PlatformClient.ModelApi.Get<PDTO.ModelDto>(Identifier, ModelGetEmbeddableFields.Backend_System)).Data;
7078
var token = (await sdk.PlatformClient.TokenApi.Create(model.Id, new List<PDTO.ModelTokenScopeEnum>() { PDTO.ModelTokenScopeEnum.GroupAnalytics }));
7179

@@ -83,14 +91,14 @@ await WrapExceptions(async () =>
8391
// keep a dictionary of components using most of the computation time
8492
Dictionary<string, ComponentStats> Components = new Dictionary<string, ComponentStats>();
8593

86-
Console.WriteLine($"Fetch computations from log between {timestampFrom} and {timestampTo} ...");
94+
logMessage($"Fetch computations from log between {timestampFrom} and {timestampTo} ...");
8795
var response = await gbSdk.Model.QueryComputations(model.GeometryBackendId, timestampFrom, timestampTo, order: order);
8896

8997
while ( true )
9098
{
9199
if (response.Computations.Count > 0)
92100
{
93-
Console.WriteLine($"{response.Computations.First().Timestamp} - {response.Computations.Last().Timestamp}: {response.Computations.Count} computations");
101+
logMessage($"{response.Computations.First().Timestamp} - {response.Computations.Last().Timestamp}: {response.Computations.Count} computations");
94102
}
95103

96104
computations.AddRange(response.Computations);
@@ -115,7 +123,7 @@ await WrapExceptions(async () =>
115123
{
116124
if (response.Computations.Last().Timestamp < long.Parse(timestampFrom))
117125
{
118-
Console.WriteLine($"Workaround for timestamp filter bug: stop querying computations.");
126+
logMessage($"Workaround for timestamp filter bug: stop querying computations.");
119127
break;
120128
}
121129
}
@@ -125,12 +133,13 @@ await WrapExceptions(async () =>
125133

126134
if (computations.Count == 0)
127135
{
128-
Console.WriteLine($"No computations found.");
136+
logMessage($"No computations found.");
129137
return;
130138
}
131139

132140
// timestamp of the youngest computation
133141
var lastComputationTimestamp = computations.First().Timestamp.ToString();
142+
var prefix = $"{model.Slug}--{lastComputationTimestamp}";
134143

135144
// build a csv file containing the component stats
136145
IEnumerable<ComponentStats> componentsOrderedByAvgTimeDesc = Components.Select(c => c.Value).OrderBy(c => c.AvgTime).Reverse();
@@ -141,43 +150,45 @@ await WrapExceptions(async () =>
141150
sb.AppendLine($"{c.Component.Name},{c.Component.Instance},{c.Component.NickName},{N2S(c.AvgTime)},{N2S(c.MaxTime)},{c.Count},{N2S(c.TotalTime)}");
142151
}
143152
var componentCsv = sb.ToString();
144-
var componentCsvFilename = $"components-stats--{model.Slug}--{lastComputationTimestamp}.csv";
145-
Console.WriteLine($"{Environment.NewLine}Exported information about {componentsOrderedByAvgTimeDesc.Count()} components sorted by decreasing average computation time to {componentCsvFilename}.");
153+
var componentCsvFilename = $"{prefix}--components-stats.csv";
154+
logMessage($"{Environment.NewLine}Exported information about {componentsOrderedByAvgTimeDesc.Count()} components sorted by decreasing average computation time to {componentCsvFilename}.");
146155
File.WriteAllText(componentCsvFilename, componentCsv);
147156

148157
// csv file containing the stats for successful computations without exports
149-
var computationsCsvFilename = $"computations-stats--{model.Slug}--{lastComputationTimestamp}.csv";
158+
var computationsCsvFilename = $"{prefix}--computations-stats.csv";
150159
var computationsSelected = computations.Where(c => c.Status == ModelComputationStatusEnum.Success && c.Exports.Count == 0);
151160
ExportComputationsSummaryToCsv(computationsCsvFilename, computationsSelected);
152-
Console.WriteLine($"{Environment.NewLine}Exported stats of {computationsSelected.Count()} successful computations to {componentCsvFilename}.");
161+
logMessage($"{Environment.NewLine}Exported stats of {computationsSelected.Count()} successful computations to {componentCsvFilename}.");
153162

154163
// csv file containing the stats for successful exports
155-
var exportsCsvFilename = $"exports-stats--{model.Slug}--{lastComputationTimestamp}.csv";
164+
var exportsCsvFilename = $"{prefix}--exports-stats.csv";
156165
computationsSelected = computations.Where(c => c.Status == ModelComputationStatusEnum.Success && c.Exports.Count != 0);
157166
ExportComputationsSummaryToCsv(exportsCsvFilename, computationsSelected);
158-
Console.WriteLine($"{Environment.NewLine}Exported stats of {computationsSelected.Count()} successful exports to {exportsCsvFilename}.");
167+
logMessage($"{Environment.NewLine}Exported stats of {computationsSelected.Count()} successful exports to {exportsCsvFilename}.");
159168

160169
// csv file containing the stats for failed computations and exports
161-
var failedCsvFilename = $"failed-stats--{model.Slug}--{lastComputationTimestamp}.csv";
170+
var failedCsvFilename = $"{prefix}--failed-stats.csv";
162171
computationsSelected = computations.Where(c => c.Status != ModelComputationStatusEnum.Success);
163172
ExportComputationsSummaryToCsv(failedCsvFilename, computationsSelected);
164-
Console.WriteLine($"{Environment.NewLine}Exported stats of {computationsSelected.Count()} failed computations and exports to {failedCsvFilename}.");
173+
logMessage($"{Environment.NewLine}Exported stats of {computationsSelected.Count()} failed computations and exports to {failedCsvFilename}.");
165174

166175
// json file containing the stats for all computations
167-
var jsonFilename = $"computations-stats--{model.Slug}--{lastComputationTimestamp}.json";
176+
var jsonFilename = $"{prefix}--computations-stats.json";
168177
File.WriteAllText(jsonFilename, JsonConvert.SerializeObject(computations, Formatting.Indented));
169-
Console.WriteLine($"{Environment.NewLine}Exported stats of all computations to {jsonFilename}.");
178+
logMessage($"{Environment.NewLine}Exported stats of all computations to {jsonFilename}.");
170179

171180
// find and report extreme computations
172-
Console.WriteLine($"{Environment.NewLine}Summary statistics of successful computations:");
181+
logMessage($"{Environment.NewLine}Summary statistics of successful computations:");
173182
var successfullComputations = computations.Where(c => c.Status == ModelComputationStatusEnum.Success);
174-
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeSolver, "Milliseconds used by Grasshopper solver (time_solver)");
175-
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeSolverCollect, "Milliseconds used to collect data after solution (time_solver_collect)");
176-
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeStorage, "Milliseconds used to store data (time_storage)");
177-
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeProcessing, "Milliseconds used to process the request (time_processing)");
178-
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeWait, "Milliseconds the request waited before being processed (time_wait)");
179-
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeCompletion, "Milliseconds used to answer the request (time_completion)");
180-
PrintSummaryStatistic(successfullComputations, c => c.Stats.SizeAssets, "Size of resulting data in bytes (size_assets)");
183+
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeSolver, "Milliseconds used by Grasshopper solver (time_solver)", logMessage);
184+
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeSolverCollect, "Milliseconds used to collect data after solution (time_solver_collect)", logMessage);
185+
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeStorage, "Milliseconds used to store data (time_storage)", logMessage);
186+
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeProcessing, "Milliseconds used to process the request (time_processing)", logMessage);
187+
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeWait, "Milliseconds the request waited before being processed (time_wait)", logMessage);
188+
PrintSummaryStatistic(successfullComputations, c => c.Stats.TimeCompletion, "Milliseconds used to answer the request (time_completion)", logMessage);
189+
PrintSummaryStatistic(successfullComputations, c => c.Stats.SizeAssets, "Size of resulting data in bytes (size_assets)", logMessage);
190+
191+
File.WriteAllText($"{prefix}--log.txt", log.ToString());
181192
});
182193
}
183194

@@ -193,7 +204,7 @@ void ExportComputationsSummaryToCsv(string filename, IEnumerable<GeometryBackend
193204
File.WriteAllText(filename, csv);
194205
}
195206

196-
void PrintSummaryStatistic(IEnumerable<GeometryBackendModelComputationDto> computations, Func<GeometryBackendModelComputationDto, int> selector, string description)
207+
void PrintSummaryStatistic(IEnumerable<GeometryBackendModelComputationDto> computations, Func<GeometryBackendModelComputationDto, int> selector, string description, Action<string> logMessage)
197208
{
198209
var values = computations.Select(c => selector(c)).ToList();
199210
var min = values.Min();
@@ -203,7 +214,7 @@ void PrintSummaryStatistic(IEnumerable<GeometryBackendModelComputationDto> compu
203214
var sortedNumbers = values.OrderBy(n => n).ToList();
204215
Func<double, string> p = (double d) => N2S(CalculatePercentile(sortedNumbers, d));
205216

206-
Console.WriteLine($"{description} - Min,Avg,Mag: {min},{N2S(avg)},{max} - p01,p05,p10,p25,p50,p75,p90,p95,p99: {p(0.01)},{p(0.05)},{p(0.1)},{p(0.25)},{p(0.5)},{p(0.75)},{p(0.9)},{p(0.95)},{p(0.99)}");
217+
logMessage($"{description} - Min,Avg,Mag: {min},{N2S(avg)},{max} - p01,p05,p10,p25,p50,p75,p90,p95,p99: {p(0.01)},{p(0.05)},{p(0.1)},{p(0.25)},{p(0.5)},{p(0.75)},{p(0.9)},{p(0.95)},{p(0.99)}");
207218
}
208219

209220
string N2S(double n)

Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.0.0.0")]
36-
[assembly: AssemblyFileVersion("1.0.0.0")]
35+
[assembly: AssemblyVersion("1.1.0.0")]
36+
[assembly: AssemblyFileVersion("1.1.0.0")]

0 commit comments

Comments
 (0)