public void ArrayEnumerationIsFaster() { // # Arrange IBenchmarkValidator validator = LatencyValidatorFactory.Builder .IfTreatmentFasterThanBaseline(byAtLeast: 10.Percent(), withConfidenceLevel: 0.99, then: LatencyValidatorBehavior.Pass) .Otherwise(LatencyValidatorBehavior.Fail); var validators = new[] { validator }; // # Act ISpecificBenchmarkRunner runner = benchmarkRunner.ForBenchmarkContainer <ArrayEnumerationIsFaster_Benchmarks>(); // Not strictly necessary // TODO: We should change how RunBenchmark is called to incorporate limits on how much time we are willing to spend //{ // BenchmarkRunEstimate runEstimate = runner.GetRunEstimate(validators); // if (runEstimate.EstimatedTime > TimeSpan.FromMinutes(2)) // { // Assert.Inconclusive("Inconclusive - It would take too long"); // } //} BenchmarkResults benchmarkResults = runner.RunBenchmark(forValidators: validators); BenchmarkAssert.ValidatorsPassed( validators, benchmarkResults, assertFailDelegate: Assert.Fail); }
public void Should_report_valid_markdown_format() { CleanPerfDir(_perfResultsPath); SystemTime.UtcNow = () => new DateTime(2017, 3, 13); var mdOutput = new MarkdownBenchmarkOutput(_perfResultsPath); var fakeBenchmarkResults = new BenchmarkResults("NBench.FakeBenchmark", new BenchmarkSettings(TestMode.Test, RunMode.Iterations, 30, 1000, new List <IBenchmarkSetting>(), new ConcurrentDictionary <MetricName, MetricsCollectorSelector>()), new List <BenchmarkRunReport>() { new BenchmarkRunReport(TimeSpan.FromSeconds(3), new List <MetricRunReport>() { new MetricRunReport(new CounterMetricName("FakeCounterMetric"), "bytes", 0d, Stopwatch.Frequency), new MetricRunReport(new GcMetricName(GcMetric.TotalCollections, GcGeneration.Gen2), "collections", 0d, Stopwatch.Frequency), new MetricRunReport(new MemoryMetricName(MemoryMetric.TotalBytesAllocated), "operations", 0d, Stopwatch.Frequency), }, new List <Exception>()) }); var fakeBenchmarkFinalResults = new BenchmarkFinalResults(fakeBenchmarkResults, new List <AssertionResult>() { new AssertionResult(new CounterMetricName("FakeCounterMetric"), "[Counter] FakeCounterMetric Assertion Result", true), new AssertionResult(new GcMetricName(GcMetric.TotalCollections, GcGeneration.Gen2), "TotalCollections [Gen2] Assertion Result", true), new AssertionResult(new MemoryMetricName(MemoryMetric.TotalBytesAllocated), "TotalBytesAllocated Assertion Result", true) }); mdOutput.WriteBenchmark(fakeBenchmarkFinalResults); var fakePerfResultsFile = Directory.GetFiles(_perfResultsPath, "NBench.FakeBenchmark*", SearchOption.AllDirectories); Approvals.Verify(File.ReadAllText(fakePerfResultsFile.FirstOrDefault()), ScrubSysInfo); }
public override int Invoke(IEnumerable <string> arguments) { List <string> extra = Options.Parse(arguments); if (showHelp) { Options.WriteOptionDescriptions(CommandSet.Out); return((int)ErrorNumber.HelpRequested); } MainClass.PrintCopyright(); if (MainClass.Debug) { DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; } if (MainClass.Verbose) { DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; } Statistics.AddCommand("benchmark"); if (extra.Count != 0) { DicConsole.ErrorWriteLine("Too many arguments."); return((int)ErrorNumber.UnexpectedArgumentCount); } DicConsole.DebugWriteLine("Benchmark command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Benchmark command", "--verbose={0}", MainClass.Verbose); Benchmark.InitProgressEvent += Progress.InitProgress; Benchmark.UpdateProgressEvent += Progress.UpdateProgress; Benchmark.EndProgressEvent += Progress.EndProgress; BenchmarkResults results = Benchmark.Do(bufferSize * 1024 * 1024, blockSize); DicConsole.WriteLine("Took {0} seconds to fill buffer, {1:F3} MiB/sec.", results.FillTime, results.FillSpeed); DicConsole.WriteLine("Took {0} seconds to read buffer, {1:F3} MiB/sec.", results.ReadTime, results.ReadSpeed); DicConsole.WriteLine("Took {0} seconds to entropy buffer, {1:F3} MiB/sec.", results.EntropyTime, results.EntropySpeed); foreach (KeyValuePair <string, BenchmarkEntry> entry in results.Entries) { DicConsole.WriteLine("Took {0} seconds to {1} buffer, {2:F3} MiB/sec.", entry.Value.TimeSpan, entry.Key, entry.Value.Speed); } DicConsole.WriteLine("Took {0} seconds to do all algorithms at the same time, {1:F3} MiB/sec.", results.TotalTime, results.TotalSpeed); DicConsole.WriteLine("Took {0} seconds to do all algorithms sequentially, {1:F3} MiB/sec.", results.SeparateTime, results.SeparateSpeed); DicConsole.WriteLine(); DicConsole.WriteLine("Max memory used is {0} bytes", results.MaxMemory); DicConsole.WriteLine("Min memory used is {0} bytes", results.MinMemory); return((int)ErrorNumber.NoError); }
public static void Resultout(BenchmarkResults results, string resultInfo = "") { Console.WriteLine(resultInfo); foreach (var result in results.SignerResults) { Console.WriteLine(result.Signer + " {0} {1} {2}", result.Frr, result.Far, result.Aer); } Console.WriteLine("Avg {0} {1} {2}", results.FinalResult.Frr, results.FinalResult.Far, results.FinalResult.Aer); }
public void RunTest(PerformanceScenario scenario) { Scenario = scenario.Name; double time; BenchmarkResults.TryGetValue(scenario.Name, out time); ExpectedRenderTime = time; _Provider.Clear(); View = scenario.View; }
private static BenchmarkResults runBenchmarks(int maxSize) { var results = new BenchmarkResults(); for (int size = 0; size < maxSize; size++) { foreach (var alg in algorithms) { results.Add((alg, size, measureTime(size, alg))); } } return(results); }
private void WriteResultsToCsvFile(BenchmarkResults testResults) { using (var stream = File.Open($"Results/DWABench_results_{executionTime.ToString("yyyyMMdd")}.csv", FileMode.Append)) using (var writer = new StreamWriter(stream)) using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture)) { if (stream.Length > 0) { // Don't write the header again. csv.Configuration.HasHeaderRecord = false; } csv.WriteRecords(new BenchmarkResults[] { testResults }); } }
public static string[] BenchmarkResToLines(BenchmarkResults results) { var res = new List <string>(); foreach (var result in results.SignerResults) { var newLine = result.Signer + " " + result.Frr.ToString() + " " + result.Far.ToString() + " " + result.Aer.ToString(); res.Add(newLine); } var finalResult = results.FinalResult; var finalLine = "Avg " + finalResult.Frr + " " + finalResult.Frr + " " + finalResult.Aer; res.Add(finalLine); return(res.ToArray()); }
public async Task RunBenchmarkAsync(string hostHttpsUrl, int httpsPort, DateTime executionTime) { this.executionTime = executionTime; PrintHardwareInformation(); string connectionString = PrepareTestDatabaseConnectionString(); logger.LogDebug($"Starting internal Web server using address '{hostHttpsUrl}' ..."); this.server = StartWebApiServer(httpsPort, connectionString); bool serverReady = await WaitForServerToBeReadyAsync(); if (!serverReady) { logger.LogError("Unable to access the server within 120 seconds. Exiting..."); this.server.Kill(true); KillWebApiServers(); return; } int.TryParse(configuration["phase1-records"], out int recordsToInsert); recordsToInsert = recordsToInsert <= 0 ? DEFAULT_PHASE1_RECORDS : recordsToInsert; TimeSpan elapsedTime = await phase1.ExecuteScenarioAsync(recordsToInsert); int.TryParse(configuration["phase2-users"], out int numberOfConcurrentUsers); int.TryParse(configuration["phase2-seconds"], out int secondsToRun); secondsToRun = secondsToRun <= 0 ? DEFAULT_PHASE2_SECONDS : secondsToRun; numberOfConcurrentUsers = numberOfConcurrentUsers <= 0 ? Environment.ProcessorCount - 1 //by default we leave one CPU thread for other tasks - this increases the performance : numberOfConcurrentUsers; int totalRequests = await phase2.ExecuteScenarioAsync(secondsToRun, numberOfConcurrentUsers); BenchmarkResults testResults = new BenchmarkResults() { ExecutionTimeUtc = executionTime.ToString("yyyy-MM-dd HH:mm:ss"), Phase1Time = (decimal)elapsedTime.TotalSeconds, Phase2Time = secondsToRun, Phase2TotalRequests = totalRequests, Phase2RequestsPerSecond = totalRequests / secondsToRun, ErrorsOccured = phase1.ErrorsOccured || phase2.ErrorsOccured }; WriteResultsToCsvFile(testResults); }
public BenchmarkResults Run() { var results = new BenchmarkResults(); for (var i = 1; i <= PassesCount; i++) { var passInfo = new PassInfo(i); var startTime = DateTime.Now; Action(passInfo); var elapsed = startTime - DateTime.Now; results.AddPass(i, elapsed); } return LastResults = results; }
public static void RunBenchmark(BenchmarkData benchmarkData) { // Prepare benchmark Console.Clear(); currentBenchmarkResults = new BenchmarkResults(); currentBenchmarkResults.SetData(benchmarkData); // Run 2 benchmarks. One for each type SeparationLine(); RunTests(benchmarkData.changesAmount, benchmarkData.testsAmount, benchmarkData.benchmark1); SeparationLine(); RunTests(benchmarkData.changesAmount, benchmarkData.testsAmount, benchmarkData.benchmark2); SeparationLine(); // Finish benchmark DisplayResults(); }
public void EnumerableEnumerationIsFaster() { // # Arrange ISpecificBenchmarkRunner runner = benchmarkRunner/*Factory? Context? TODO*/ .For( baseline: (EnumerableEnumerationIsFaster_Benchmarks container) => container.ListEnumeration(), treatment: (EnumerableEnumerationIsFaster_Benchmarks container) => container.EnumerableEnumeration()); IBenchmarkValidator validator = LatencyValidatorFactory.Builder // treatment: EnumerableEnumeration <slower than> baseline: ListEnumeration .IfTreatmentSlowerThanBaseline(byAtLeast: 20.Percent(), withConfidenceLevel: 0.95, then: LatencyValidatorBehavior.Pass) .Otherwise(LatencyValidatorBehavior.Fail); // # Act BenchmarkResults benchmarkResults = runner.RunBenchmark( // TODO: Would 'sampleSizeDeterminers' be better? I mean, THAT name is horrible, but more accurate forValidator: validator); // # Assert BenchmarkAssert.ValidatorsPassed( new [] { validator }, benchmarkResults, assertFailDelegate: Assert.Fail); // NOTE - same as above, more succinctly... //DefaultBenchmarkRunner.Instance // .For( // baseline: (EnumerableEnumerationIsFaster_Benchmarks container) => container.ListEnumeration(), // treatment: (EnumerableEnumerationIsFaster_Benchmarks container) => container.EnumerableEnumeration()) // // TODO: Would rather Run() and then Assert(), but both require the arguments right now so wouldn't be able to do that in-line reading like a sentence // // We are trying to represent... // // "For baseline ListEnumeration and treatment EnumerableEnumeration if treatment is slower than baseline with confidence level 0.9999 then pass // // otherwise fail by calling Assert.Fail()" // .RunWithValidatorAndAssertPassed( // LatencyValidatorFactory.Builder // .IfTreatmentSlowerThanBaseline( // byAtLeast: 10.Percent(), // withConfidenceLevel: 0.9999, // then: LatencyValidatorBehavior.Pass) // .Otherwise(LatencyValidatorBehavior.Fail), // assertFailDelegate: Assert.Fail); }
protected void OnBtnStart(object sender, EventArgs e) { checksumTimes = new Dictionary <string, double>(); Benchmark.UpdateProgressEvent += UpdateProgress; stkProgress.Visible = true; lblProgress.Text = ""; btnClose.Enabled = false; btnStart.Enabled = false; nmuBufferSize.Enabled = false; nmuBlockSize.Enabled = false; Thread thread = new Thread(() => { counter = step = (int)(nmuBufferSize.Value * 1024 * 1024 / nmuBlockSize.Value) % 3333; // TODO: Able to cancel! results = Benchmark.Do((int)(nmuBufferSize.Value * 1024 * 1024), (int)nmuBlockSize.Value); Application.Instance.Invoke(Finish); }); thread.Start(); }
private static void printBenchmarkResultsToFile(BenchmarkResults results, string folder) { var algResultFileWriters = new Dictionary <MatrixMultAlgorithm, StreamWriter>(); foreach (var alg in algorithms) { algResultFileWriters[alg] = new StreamWriter($"{folder}/{alg.Name}.csv"); } foreach (var result in results) { var(alg, size, time) = result; var stream = algResultFileWriters[alg]; stream.WriteLine($"{size}\t{time}"); } foreach (var stream in algResultFileWriters.Values) { stream.Dispose(); } }
static void DisplayResults() { WriteLines(resultsTitle); WriteLines(ResultsDescription); SeparationLineSmall(); WriteLines(ResultsAnalysis); SeparationLineSmall(); WriteLines(resultsBottomText); SeparationLine(); currentBenchmarkResults = null; var k = Console.ReadKey(); if (k.Key == key_runSameBenchmarkAgain) { RunBenchmark(VarEncBenchmark.currentBenchmarkData); } else { VarEncBenchmark.StartProgram(); } }
internal static void DoBenchmark(BenchmarkOptions options) { Dictionary <string, double> checksumTimes = new Dictionary <string, double>(); Core.Benchmark.InitProgressEvent += Progress.InitProgress; Core.Benchmark.UpdateProgressEvent += Progress.UpdateProgress; Core.Benchmark.EndProgressEvent += Progress.EndProgress; BenchmarkResults results = Core.Benchmark.Do(options.BufferSize * 1024 * 1024, options.BlockSize); DicConsole.WriteLine("Took {0} seconds to fill buffer, {1:F3} MiB/sec.", results.FillTime, results.FillSpeed); DicConsole.WriteLine("Took {0} seconds to read buffer, {1:F3} MiB/sec.", results.ReadTime, results.ReadSpeed); DicConsole.WriteLine("Took {0} seconds to entropy buffer, {1:F3} MiB/sec.", results.EntropyTime, results.EntropySpeed); foreach (KeyValuePair <string, BenchmarkEntry> entry in results.Entries) { checksumTimes.Add(entry.Key, entry.Value.TimeSpan); DicConsole.WriteLine("Took {0} seconds to {1} buffer, {2:F3} MiB/sec.", entry.Value.TimeSpan, entry.Key, entry.Value.Speed); } DicConsole.WriteLine("Took {0} seconds to do all algorithms at the same time, {1} MiB/sec.", results.TotalTime, results.TotalSpeed); DicConsole.WriteLine("Took {0} seconds to do all algorithms sequentially, {1} MiB/sec.", results.SeparateTime, results.SeparateSpeed); DicConsole.WriteLine(); DicConsole.WriteLine("Max memory used is {0} bytes", results.MaxMemory); DicConsole.WriteLine("Min memory used is {0} bytes", results.MinMemory); Core.Statistics.AddCommand("benchmark"); Core.Statistics.AddBenchmark(checksumTimes, results.EntropyTime, results.TotalTime, results.SeparateTime, results.MaxMemory, results.MinMemory); }
public async void PushBenchmarkResults() { Logger.Log.Info("Sending benchmark result"); try { BenchmarkResults.Clear(); using var client = new HttpClient(); var version = Assembly.GetExecutingAssembly().GetName().Version; client.DefaultRequestHeaders.Add("User-Agent", $"FloatTool/{App.VersionCode}"); string paramedURL = $"/AddBenchmark.php?cpu={CurrentCpuName}&threads={ThreadCount}&multicore={MultithreadedSpeed}&singlecore={SinglethreadedSpeed}"; HttpResponseMessage response = await client.GetAsync(Utils.API_URL + paramedURL); response.EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); Logger.Log.Info("Sended benchmark result"); } catch (Exception ex) { Logger.Log.Error("Error sending benchmark result", ex); } CanPublish = false; PollBenchmarkResults(); }
public static void ResultsToTxt(BenchmarkResults results, string fileName) { TxtHelper.Save(TxtHelper.BenchmarkResToLines(results), fileName); }
public BenchmarkFinalResults AssertResults(BenchmarkResults result) { var assertionResults = BenchmarkAssertionRunner.RunAssertions(Settings, result); return(new BenchmarkFinalResults(result, assertionResults)); }
public async void PollBenchmarkResults() { Logger.Log.Info("Getting benchmark results"); IsUpdatingEnabled = false; try { BenchmarkResults.Clear(); using var client = new HttpClient(); HttpResponseMessage response = await client.GetAsync(Utils.API_URL + "/LoadBenchmarks.php"); response.EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); dynamic result = JsonConvert.DeserializeObject(responseBody); if (result["status"] == 200 && result["count"] > 0) { float maxspeed = result.items[0].multithread; foreach (var benchmark in result.items) { float percentage = (float)benchmark.multithread / maxspeed; float reverse = 1 - percentage; string cpuName = Utils.ShortCpuName((string)benchmark.name); var currentFill = AMDBrush; if (cpuName == CurrentCpuName) { currentFill = CurrentBrush; MultithreadedSpeed = Math.Max((int)benchmark.multithread, MultithreadedSpeed); SinglethreadedSpeed = Math.Max((int)benchmark.singlethread, SinglethreadedSpeed); } else if (cpuName.StartsWith("Intel")) { currentFill = IntelBrush; } string threadsString = Application.Current.Resources["m_Threads"] as string; if ((int)benchmark.threads == 1) { threadsString = Application.Current.Resources["m_Thread"] as string; } BenchmarkResults.Add(new BenchmarkResult { CpuName = cpuName, ThreadCount = $"{benchmark.threads} {threadsString} [{benchmark.version}]", MultithreadedScore = $"{(int)benchmark.multithread:n0}", SinglethreadedScore = $"{(int)benchmark.singlethread:n0}", FillSize = new GridLength(percentage, GridUnitType.Star), EmptySize = new GridLength(reverse, GridUnitType.Star), FillBrush = currentFill }); } } Logger.Log.Info("Benchmark results loaded"); } catch (Exception ex) { BenchmarkResults.Add(new BenchmarkResult { CpuName = "Error loading benchmark table.", FillSize = new GridLength(0, GridUnitType.Star), EmptySize = new GridLength(1, GridUnitType.Star), }); Logger.Log.Error("Error getting benchmark results", ex); } IsUpdatingEnabled = true; }
/// <summary> /// Base constructor for benchmark. /// </summary> /// <param name="numberOfRuns"> /// Number of times to run a benchmark. /// </param> public BaseBenchmark(int numberOfRuns) { TestResult = new BenchmarkResults(numberOfRuns); }
private static void Resultout(BenchmarkResults result, Signer signer) { Console.WriteLine(signer.ID + " " + result.FinalResult.Frr.ToString() + " " + result.FinalResult.Far.ToString() + " " + result.FinalResult.Aer.ToString()); }
internal static async Task RunAsync(string inputDir, string outputDir, int procId, int maxThreads) { //stop worker process after 3 days DateTime stopTime = DateTime.Now.AddHours(71); //delayed start await Task.Delay(100 *procId); OutputDirectory = Directory.CreateDirectory(outputDir); var initSuccess = await Init(inputDir); if (!initSuccess) { return; } Console.WriteLine($"{DateTime.Now}: Worker is running."); if (!Console.IsInputRedirected) { Console.WriteLine("Press 'A' to abort."); } while (DateTime.Now < stopTime) { StringBuilder debugInfo = new StringBuilder(); debugInfo.AppendLine(DateTime.Now.ToString()); if (!Console.IsInputRedirected) { if (Console.KeyAvailable && Console.ReadKey().Key == ConsoleKey.A) { Console.WriteLine($"{DateTime.Now}: Aborting..."); return; } } var logger = new SimpleConsoleLogger();//default log level: Information logger.Logged += (m, e, l) => { debugInfo.AppendLine(m); if (e != null) { debugInfo.AppendLine(e.ToString()); } if (l == LogLevel.Error || l == LogLevel.Critical) { CurrentResultType = "Error"; } }; CurrentBenchmark = await GetNextBenchmark(); if (CurrentBenchmark is null) { return; } CurrentBenchmark.Logger = logger; Console.WriteLine($"{DateTime.Now}: Starting benchmark..."); try { if (maxThreads > 0) { CurrentResults = CurrentBenchmark.Execute(maxThreads); } else { CurrentResults = CurrentBenchmark.Execute(true);//default: no restriction } CurrentResultType = "Success"; } catch (Exception exc) { CurrentResultType = "Error"; Console.WriteLine(exc.ToString()); debugInfo.AppendLine(exc.ToString()); var debugFileName = $"Result_{CurrentBenchmarkId}_Log.txt"; debugFileName = Path.Combine(OutputDirectory.ToString(), debugFileName); File.WriteAllText(debugFileName, debugInfo.ToString()); if (!Program.Offline) { var blob = Container.GetBlockBlobReference($"Results/{debugFileName}"); await blob.DeleteIfExistsAsync(); await blob.UploadFromFileAsync(debugFileName); } continue; } await ProcessResults(); if (Program.Offline) {//delete input config and lock after processing File.Delete(Path.Combine(InputDirectory.ToString(), CurrentBenchmarkId + ".json")); File.Delete(Path.Combine(InputDirectory.ToString(), CurrentBenchmarkId + ".json.lock")); } else { await Queue.DeleteMessageAsync(CurrentMessage); } //LogProcessor.Dump(logger); // MongoDB // TableStorage // Json => utólag, json-ben szűrni lehet // DynamoDB ==> MongoDB $$$$$$$ // DateTime, MachineName, ....ExecutionTime,..., ResultType, Result json{40*60 táblázat} //benchmark.Dump(filename, config.ToKeyValuePairs()); } }
//TODO: need to respect TestMode https://github.com/petabridge/NBench/issues/6 public static IReadOnlyList <AssertionResult> RunAssertions(BenchmarkSettings settings, BenchmarkResults results) { Contract.Requires(settings != null); var assertionResults = new List <AssertionResult>(); // Not in testing mode, therefore we don't need to apply these assertions if (settings.TestMode == TestMode.Measurement) { return(assertionResults); } // collect all benchmark settings with non-empty assertions IList <IBenchmarkSetting> allSettings = settings.CounterBenchmarks.Concat <IBenchmarkSetting>(settings.GcBenchmarks) .Concat(settings.MemoryBenchmarks).Where(x => !x.Assertion.Equals(Assertion.Empty)) .ToList(); foreach (var setting in allSettings) { var stats = results.StatsByMetric[setting.MetricName]; double valueToBeTested; if (setting.AssertionType == AssertionType.Throughput) { valueToBeTested = stats.PerSecondStats.Average; } else { valueToBeTested = stats.Stats.Average; } var assertionResult = AssertionResult.CreateResult(setting.MetricName, stats.Unit, valueToBeTested, setting.Assertion); assertionResults.Add(assertionResult); } return(assertionResults); }
/// <summary> /// Runs the benchmark /// </summary> public void Run() { Result = default(TResult); // Setup if (SetupFunc != null) { SetupFunc(this); } int runs = 0; var startTime = DateTime.Now; double minRunSeconds = double.MaxValue; double maxRunSeconds = 0; double totalRunSeconds = 0; // Run the benchmark for (int i = 0; i < Iterations; i++) { var runStart = DateTime.Now; // Execute the run Result = ExecuteFunc(this); runs++; // Count the run time var runEnd = DateTime.Now; var runTime = runEnd - runStart; var runSeconds = runTime.TotalSeconds; if (runSeconds < minRunSeconds) { minRunSeconds = runSeconds; } if (runSeconds > maxRunSeconds) { maxRunSeconds = runSeconds; } totalRunSeconds += runSeconds; } var endTime = DateTime.Now; // Calculate the results if (Math.Abs(minRunSeconds - double.MaxValue) < Math.E) { minRunSeconds = 0; } var totalTime = endTime - startTime; var totalSeconds = totalTime.TotalSeconds; var secondsPerRun = totalSeconds / runs; // Set up the results Results = new BenchmarkResults { Runs = runs, TotalSeconds = totalSeconds, SecondsPerRun = secondsPerRun, MinRunSeconds = minRunSeconds, MaxRunSeconds = maxRunSeconds, TotalRunSeconds = totalRunSeconds }; // Tear down if (TearDownFunc != null) { TearDownFunc(this); } }