Statistics.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Text;
  7. namespace ARMeilleure
  8. {
  9. public static class Statistics
  10. {
  11. private const int ReportMaxFunctions = 100;
  12. #pragma warning disable CS0169
  13. [ThreadStatic]
  14. private static Stopwatch _executionTimer;
  15. #pragma warning restore CS0169
  16. private static ConcurrentDictionary<ulong, long> _ticksPerFunction;
  17. static Statistics()
  18. {
  19. _ticksPerFunction = new ConcurrentDictionary<ulong, long>();
  20. }
  21. public static void InitializeTimer()
  22. {
  23. #if M_PROFILE
  24. if (_executionTimer == null)
  25. {
  26. _executionTimer = new Stopwatch();
  27. }
  28. #endif
  29. }
  30. internal static void StartTimer()
  31. {
  32. #if M_PROFILE
  33. _executionTimer.Restart();
  34. #endif
  35. }
  36. internal static void StopTimer(ulong funcAddr)
  37. {
  38. #if M_PROFILE
  39. _executionTimer.Stop();
  40. long ticks = _executionTimer.ElapsedTicks;
  41. _ticksPerFunction.AddOrUpdate(funcAddr, ticks, (key, oldTicks) => oldTicks + ticks);
  42. #endif
  43. }
  44. internal static void ResumeTimer()
  45. {
  46. #if M_PROFILE
  47. _executionTimer.Start();
  48. #endif
  49. }
  50. internal static void PauseTimer()
  51. {
  52. #if M_PROFILE
  53. _executionTimer.Stop();
  54. #endif
  55. }
  56. public static string GetReport()
  57. {
  58. int count = 0;
  59. StringBuilder sb = new StringBuilder();
  60. sb.AppendLine(" Function address | Time");
  61. sb.AppendLine("--------------------------");
  62. KeyValuePair<ulong, long>[] funcTable = _ticksPerFunction.ToArray();
  63. foreach (KeyValuePair<ulong, long> kv in funcTable.OrderByDescending(x => x.Value))
  64. {
  65. long timeInMs = (kv.Value * 1000) / Stopwatch.Frequency;
  66. sb.AppendLine($" 0x{kv.Key:X16} | {timeInMs} ms");
  67. if (count++ >= ReportMaxFunctions)
  68. {
  69. break;
  70. }
  71. }
  72. return sb.ToString();
  73. }
  74. }
  75. }