ProfileHelper.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Disable some warnings since this class compiles out large parts of the code depending on compiler directives
  2. #pragma warning disable 0162
  3. #pragma warning disable 0414
  4. #pragma warning disable 0429
  5. //#define PROFILE // Uncomment to enable profiling
  6. //#define KEEP_SAMPLES
  7. using System;
  8. using System.Collections.Generic;
  9. namespace Pathfinding {
  10. public class Profile {
  11. const bool PROFILE_MEM = false;
  12. public readonly string name;
  13. readonly System.Diagnostics.Stopwatch watch;
  14. int counter;
  15. long mem;
  16. long smem;
  17. #if KEEP_SAMPLES
  18. List<float> samples = new List<float>();
  19. #endif
  20. int control = 1 << 30;
  21. const bool dontCountFirst = false;
  22. public int ControlValue () {
  23. return control;
  24. }
  25. public Profile (string name) {
  26. this.name = name;
  27. watch = new System.Diagnostics.Stopwatch();
  28. }
  29. public static void WriteCSV (string path, params Profile[] profiles) {
  30. #if KEEP_SAMPLES
  31. var s = new System.Text.StringBuilder();
  32. s.AppendLine("x, y");
  33. foreach (var profile in profiles) {
  34. for (int i = 0; i < profile.samples.Count; i++) {
  35. s.AppendLine(profile.name + ", " + profile.samples[i].ToString("R"));
  36. }
  37. }
  38. System.IO.File.WriteAllText(path, s.ToString());
  39. #endif
  40. }
  41. public void Run (System.Action action) {
  42. Start();
  43. action();
  44. Stop();
  45. }
  46. [System.Diagnostics.ConditionalAttribute("PROFILE")]
  47. public void Start () {
  48. if (PROFILE_MEM) {
  49. smem = GC.GetTotalMemory(false);
  50. }
  51. if (dontCountFirst && counter == 1) return;
  52. watch.Start();
  53. }
  54. [System.Diagnostics.ConditionalAttribute("PROFILE")]
  55. public void Stop () {
  56. counter++;
  57. if (dontCountFirst && counter == 1) return;
  58. watch.Stop();
  59. if (PROFILE_MEM) {
  60. mem += GC.GetTotalMemory(false)-smem;
  61. }
  62. #if KEEP_SAMPLES
  63. samples.Add((float)watch.Elapsed.TotalMilliseconds);
  64. watch.Reset();
  65. #endif
  66. }
  67. [System.Diagnostics.ConditionalAttribute("PROFILE")]
  68. /// <summary>Log using Debug.Log</summary>
  69. public void Log () {
  70. UnityEngine.Debug.Log(ToString());
  71. }
  72. [System.Diagnostics.ConditionalAttribute("PROFILE")]
  73. /// <summary>Log using System.Console</summary>
  74. public void ConsoleLog () {
  75. #if !NETFX_CORE || UNITY_EDITOR
  76. System.Console.WriteLine(ToString());
  77. #endif
  78. }
  79. [System.Diagnostics.ConditionalAttribute("PROFILE")]
  80. public void Stop (int control) {
  81. counter++;
  82. if (dontCountFirst && counter == 1) return;
  83. watch.Stop();
  84. if (PROFILE_MEM) {
  85. mem += GC.GetTotalMemory(false)-smem;
  86. }
  87. if (this.control == 1 << 30) this.control = control;
  88. else if (this.control != control) throw new Exception("Control numbers do not match " + this.control + " != " + control);
  89. }
  90. [System.Diagnostics.ConditionalAttribute("PROFILE")]
  91. public void Control (Profile other) {
  92. if (ControlValue() != other.ControlValue()) {
  93. throw new Exception("Control numbers do not match ("+name + " " + other.name + ") " + ControlValue() + " != " + other.ControlValue());
  94. }
  95. }
  96. public override string ToString () {
  97. string s = name + " #" + counter + " " + watch.Elapsed.TotalMilliseconds.ToString("0.0 ms") + " avg: " + (watch.Elapsed.TotalMilliseconds/counter).ToString("0.00 ms");
  98. if (PROFILE_MEM) {
  99. s += " avg mem: " + (mem/(1.0*counter)).ToString("0 bytes");
  100. }
  101. return s;
  102. }
  103. }
  104. }