Skip to content

Commit 05bb3db

Browse files
authored
Log progress and estimated finish time (#1909)
1 parent 3ea2129 commit 05bb3db

File tree

1 file changed

+34
-8
lines changed

1 file changed

+34
-8
lines changed

src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ internal static Summary[] Run(BenchmarkRunInfo[] benchmarkRunInfos)
5353
if (validationErrors.Any(validationError => validationError.IsCritical))
5454
return new[] { Summary.ValidationFailed(title, resultsFolderPath, logFilePath, validationErrors) };
5555

56-
var benchmarksToRunCount = supportedBenchmarks.Sum(benchmarkInfo => benchmarkInfo.BenchmarksCases.Length);
56+
int totalBenchmarkCount = supportedBenchmarks.Sum(benchmarkInfo => benchmarkInfo.BenchmarksCases.Length);
57+
int benchmarksToRunCount = totalBenchmarkCount;
5758
compositeLogger.WriteLineHeader("// ***** BenchmarkRunner: Start *****");
5859
compositeLogger.WriteLineHeader($"// ***** Found {benchmarksToRunCount} benchmark(s) in total *****");
5960
var globalChronometer = Chronometer.Start();
@@ -74,13 +75,12 @@ internal static Summary[] Run(BenchmarkRunInfo[] benchmarkRunInfos)
7475
{
7576
var runChronometer = Chronometer.Start();
7677

77-
var summary = Run(benchmarkRunInfo, benchmarkToBuildResult, resolver, compositeLogger, artifactsToCleanup, resultsFolderPath, logFilePath, ref runChronometer);
78+
var summary = Run(benchmarkRunInfo, benchmarkToBuildResult, resolver, compositeLogger, artifactsToCleanup,
79+
resultsFolderPath, logFilePath, totalBenchmarkCount, in globalChronometer, ref runChronometer, ref benchmarksToRunCount);
7880

7981
if (!benchmarkRunInfo.Config.Options.IsSet(ConfigOptions.JoinSummary))
8082
PrintSummary(compositeLogger, benchmarkRunInfo.Config, summary);
8183

82-
benchmarksToRunCount -= benchmarkRunInfo.BenchmarksCases.Length;
83-
compositeLogger.WriteLineHeader($"// ** Remained {benchmarksToRunCount} benchmark(s) to run **");
8484
LogTotalTime(compositeLogger, runChronometer.GetElapsed().GetTimeSpan(), summary.GetNumberOfExecutedBenchmarks(), message: "Run time");
8585
compositeLogger.WriteLine();
8686

@@ -130,7 +130,10 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo,
130130
List<string> artifactsToCleanup,
131131
string resultsFolderPath,
132132
string logFilePath,
133-
ref StartedClock runChronometer)
133+
int totalBenchmarkCount,
134+
in StartedClock globalChronometer,
135+
ref StartedClock runChronometer,
136+
ref int benchmarksToRunCount)
134137
{
135138
var benchmarks = benchmarkRunInfo.BenchmarksCases;
136139
var allBuildsHaveFailed = benchmarks.All(benchmark => !buildResults[benchmark].buildResult.IsBuildSuccess);
@@ -146,8 +149,12 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo,
146149

147150
using (var powerManagementApplier = new PowerManagementApplier(logger))
148151
{
149-
foreach (var benchmark in benchmarks)
152+
bool stop = false;
153+
154+
for (int i = 0; i < benchmarks.Length && !stop; i++)
150155
{
156+
var benchmark = benchmarks[i];
157+
151158
powerManagementApplier.ApplyPerformancePlan(benchmark.Job.Environment.PowerPlanMode
152159
?? benchmark.Job.ResolveValue(EnvironmentMode.PowerPlanModeCharacteristic, EnvironmentResolver.Instance).GetValueOrDefault());
153160

@@ -171,7 +178,9 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo,
171178
}
172179

173180
if (!report.Success && config.Options.IsSet(ConfigOptions.StopOnFirstError))
174-
break;
181+
{
182+
stop = true;
183+
}
175184
}
176185
else
177186
{
@@ -193,10 +202,16 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo,
193202
}
194203

195204
if (config.Options.IsSet(ConfigOptions.StopOnFirstError) || allBuildsHaveFailed)
196-
break;
205+
{
206+
stop = true;
207+
}
197208
}
198209

199210
logger.WriteLine();
211+
212+
benchmarksToRunCount -= stop ? benchmarks.Length - i : 1;
213+
214+
LogProgress(logger, in globalChronometer, totalBenchmarkCount, benchmarksToRunCount);
200215
}
201216
}
202217

@@ -638,5 +653,16 @@ private static void Cleanup(HashSet<string> artifactsToCleanup)
638653
}
639654
}
640655
}
656+
657+
private static void LogProgress(ILogger logger, in StartedClock globalChronometer, int totalBenchmarkCount, int benchmarksToRunCount)
658+
{
659+
int executedBenchmarkCount = totalBenchmarkCount - benchmarksToRunCount;
660+
double avgSecondsPerBenchmark = globalChronometer.GetElapsed().GetTimeSpan().TotalSeconds / executedBenchmarkCount;
661+
TimeSpan fromNow = TimeSpan.FromSeconds(avgSecondsPerBenchmark * benchmarksToRunCount);
662+
DateTime estimatedEnd = DateTime.Now.Add(fromNow);
663+
string message = $"// ** Remained {benchmarksToRunCount} ({(double)benchmarksToRunCount / totalBenchmarkCount:P1}) benchmark(s) to run." +
664+
$" Estimated finish {estimatedEnd:yyyy-MM-dd H:mm} ({(int)fromNow.TotalHours}h {fromNow.Minutes}m from now) **";
665+
logger.WriteLineHeader(message);
666+
}
641667
}
642668
}

0 commit comments

Comments
 (0)