No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BenchmarkMeasure.cs 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using Unity.PerformanceTesting.Runtime;
  2. using System;
  3. using System.Diagnostics;
  4. using System.Collections.Generic;
  5. using System.Reflection;
  6. namespace Unity.PerformanceTesting.Benchmark
  7. {
  8. /// <summary>
  9. /// An interface for performing measurements which works from Performance Test Framework or from the Benchmark Framework.<para />
  10. /// This functionality is intended to be wrapped in an implemenation specific to a type of benchmark comparison. See some of the included
  11. /// benchmarking implementations in <see cref="Unity.Collections.PerformanceTests"/> such as BenchmarkContainerRunner or BenchmarkAllocatorRunner, as well as
  12. /// the documentation in the Benchmark Framework repository for examples.
  13. /// </summary>
  14. public static class BenchmarkMeasure
  15. {
  16. internal static bool ForBenchmarks = false;
  17. private static SampleGroup LastResultsInternal;
  18. private static uint LastResultsFootnotes;
  19. internal static BenchmarkResults CalculateLastResults(SampleUnit unit, BenchmarkRankingStatistic statistic)
  20. {
  21. for (int i = 0; i < LastResultsInternal.Samples.Count; i++)
  22. LastResultsInternal.Samples[i] = Utils.ConvertSample(SampleUnit.Second, unit, LastResultsInternal.Samples[i]);
  23. LastResultsInternal.Unit = unit;
  24. Utils.UpdateStatistics(LastResultsInternal);
  25. return new BenchmarkResults(LastResultsInternal, statistic, LastResultsFootnotes);
  26. }
  27. /// <summary>
  28. /// Measure a set of samples for a given performance test. This functions correctly whether called through the Performance Test Framework
  29. /// by the Unity Test Runner, or if it is called through the Benchmark framework.<para />
  30. /// This must be called when a test will be run in a parallel job, as it marks the results with a note specifying the irregularity
  31. /// of parallel jobs due to work stealing.<para />
  32. /// When running a single threaded test (job or otherwise), use <see cref="Measure(Type, int, int, Action, Action, Action)"/>
  33. /// </summary>
  34. /// <param name="perfMeasureType">A type which contains a single performance test's implementation</param>
  35. /// <param name="warmup">The number of warm up runs prior to collecting sample data</param>
  36. /// <param name="measurements">The number of runs to collect sample data from</param>
  37. /// <param name="action">The specific per-sample method to run for measurement</param>
  38. /// <param name="setup">A per-sample setup method that will not be part of measurement</param>
  39. /// <param name="teardown">A per-sample teardown method that will not be part of measurement</param>
  40. public static void MeasureParallel(Type perfMeasureType, int warmup, int measurements, Action action, Action setup = null, Action teardown = null)
  41. {
  42. Measure(perfMeasureType, warmup, measurements, action, setup, teardown);
  43. if (ForBenchmarks)
  44. LastResultsFootnotes |= BenchmarkResults.kFlagParallelJobs;
  45. }
  46. /// <summary>
  47. /// Measure a set of samples for a given performance test. This functions correctly whether called through the Performance Test Framework
  48. /// by the Unity Test Runner, or if it is called through the Benchmark framework.<para />
  49. /// This must not be called when a test will be run in a parallel job, as this does not mark the results with a note specifying the irregularity
  50. /// of parallel jobs due to work stealing.<para />
  51. /// When running a multithreaded test, use <see cref="MeasureParallel(Type, int, int, Action, Action, Action)"/>
  52. /// </summary>
  53. /// <param name="perfMeasureType">A type which contains a single performance test's implementation</param>
  54. /// <param name="warmup">The number of warm up runs prior to collecting sample data</param>
  55. /// <param name="measurements">The number of runs to collect sample data from</param>
  56. /// <param name="action">The specific per-sample method to run for measurement</param>
  57. /// <param name="setup">A per-sample setup method that will not be part of measurement</param>
  58. /// <param name="teardown">A per-sample teardown method that will not be part of measurement</param>
  59. public static void Measure(Type perfMeasureType, int warmup, int measurements, Action action, Action setup = null, Action teardown = null)
  60. {
  61. if (ForBenchmarks)
  62. {
  63. SampleGroup results = new SampleGroup(perfMeasureType.Name, SampleUnit.Second, false);
  64. results.Samples = new List<double>(measurements);
  65. Stopwatch stopwatch = Stopwatch.StartNew();
  66. for (int i = 0; i < warmup; i++)
  67. {
  68. setup?.Invoke();
  69. action();
  70. teardown?.Invoke();
  71. }
  72. for (int i = 0; i < measurements; i++)
  73. {
  74. setup?.Invoke();
  75. stopwatch.Restart();
  76. action();
  77. results.Samples.Add(stopwatch.Elapsed.TotalSeconds);
  78. teardown?.Invoke();
  79. }
  80. LastResultsInternal = results;
  81. LastResultsFootnotes = 0;
  82. // Check if NoOptimization is part of this measurement. MethodImplAttribute is not found in
  83. // CustomAttributes, and instead is a special-case found in MethodImplementationFlags.
  84. var methods = perfMeasureType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
  85. foreach (var m in methods)
  86. {
  87. if (m.MethodImplementationFlags.HasFlag(MethodImplAttributes.NoOptimization))
  88. {
  89. LastResultsFootnotes |= BenchmarkResults.kFlagNoOptimization;
  90. break;
  91. }
  92. }
  93. }
  94. else
  95. {
  96. PerformanceTesting.Measure.Method(action)
  97. .SampleGroup(perfMeasureType.Name)
  98. .SetUp(setup)
  99. .CleanUp(teardown)
  100. .WarmupCount(warmup)
  101. .MeasurementCount(measurements)
  102. .Run();
  103. }
  104. }
  105. }
  106. }