Timer.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Text;
  5. namespace BBIWARG.Utility
  6. {
  7. /// <summary>
  8. /// Stores and prints timing information for different code sections.
  9. /// </summary>
  10. internal static class Timer
  11. {
  12. /// <summary>
  13. /// dictionary of current runtimes indexed by name of the code section
  14. /// </summary>
  15. private static Dictionary<String, double> currentTimes = new Dictionary<string, double>();
  16. /// <summary>
  17. /// the maximum length for the name of a code section
  18. /// </summary>
  19. private static int maxNameLength = 1;
  20. /// <summary>
  21. /// dictionary of maximum runtimes indexed by name of the code section
  22. /// </summary>
  23. private static Dictionary<String, double> maxTimes = new Dictionary<string, double>();
  24. /// <summary>
  25. /// dictionary of minimum runtimes indexed by name of the code section
  26. /// </summary>
  27. private static Dictionary<String, double> minTimes = new Dictionary<string, double>();
  28. /// <summary>
  29. /// dictionary of the number of times the time was measured indexed by name of the code section
  30. /// </summary>
  31. private static Dictionary<String, int> numTimes = new Dictionary<string, int>();
  32. /// <summary>
  33. /// dictionary of stopwatches indexed by name of the code section
  34. /// </summary>
  35. private static Dictionary<String, Stopwatch> stopwatches = new Dictionary<string, Stopwatch>();
  36. /// <summary>
  37. /// dictionary of the sum of runtimes indexed by name of the code section
  38. /// </summary>
  39. private static Dictionary<String, double> sumTimes = new Dictionary<string, double>();
  40. /// <summary>
  41. /// used to prevent running <see cref="start"/>, <see cref="stop"/> and <see cref="outputAll"/> simultaneously from different threads
  42. /// </summary>
  43. private static Object sync = new object();
  44. /// <summary>
  45. /// Prints all collected timing information.
  46. /// </summary>
  47. public static void outputAll()
  48. {
  49. lock (sync)
  50. {
  51. StringBuilder divider = new StringBuilder();
  52. divider.Append("├-");
  53. divider.Append(new String('-', maxNameLength));
  54. divider.Append("-┼-------┼-------┤");
  55. Console.Clear();
  56. Console.WriteLine(String.Format("| {0,-" + maxNameLength + "} | {1,-5} | {2,-5} |", "NAME", "AVG.", "CUR."));
  57. Console.WriteLine(divider.ToString());
  58. foreach (String name in stopwatches.Keys)
  59. {
  60. double average = sumTimes[name] / Math.Max(numTimes[name], 1);
  61. double current = currentTimes[name];
  62. Console.WriteLine(String.Format("| {0,-" + maxNameLength + "} | {1:00.00} | {2:00.00} |", name, average, current));
  63. }
  64. }
  65. }
  66. /// <summary>
  67. /// Starts a timer for the given name and initializes the dictionaries when called for the first time with this name.
  68. /// </summary>
  69. /// <param name="name">name of the code section</param>
  70. public static void start(String name)
  71. {
  72. lock (sync)
  73. {
  74. if (!stopwatches.ContainsKey(name))
  75. {
  76. stopwatches.Add(name, new Stopwatch());
  77. minTimes.Add(name, int.MaxValue);
  78. maxTimes.Add(name, 0);
  79. sumTimes.Add(name, 0);
  80. numTimes.Add(name, 0);
  81. currentTimes.Add(name, 0);
  82. maxNameLength = Math.Max(maxNameLength, name.Length);
  83. }
  84. stopwatches[name].Restart();
  85. }
  86. }
  87. /// <summary>
  88. /// Stops the timer for the given name and stores timing information.
  89. /// </summary>
  90. /// <param name="name">name of the code section</param>
  91. public static void stop(String name)
  92. {
  93. lock (sync)
  94. {
  95. stopwatches[name].Stop();
  96. double time = Math.Round((double)stopwatches[name].ElapsedTicks / (double)Stopwatch.Frequency * 1000.0, 2);
  97. if (time < minTimes[name]) minTimes[name] = time;
  98. if (time > maxTimes[name]) maxTimes[name] = time;
  99. sumTimes[name] += time;
  100. numTimes[name]++;
  101. currentTimes[name] = time;
  102. }
  103. }
  104. }
  105. }