using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace bbiwarg.Utility { /// /// Stores and prints timing information for different code sections. /// internal static class Timer { /// /// dictionary of current runtimes indexed by name of the code section /// private static Dictionary currentTimes = new Dictionary(); /// /// the maximum length for the name of a code section /// private static int maxNameLength = 1; /// /// dictionary of maximum runtimes indexed by name of the code section /// private static Dictionary maxTimes = new Dictionary(); /// /// dictionary of minimum runtimes indexed by name of the code section /// private static Dictionary minTimes = new Dictionary(); /// /// dictionary of the number of times the time was measured indexed by name of the code section /// private static Dictionary numTimes = new Dictionary(); /// /// dictionary of stopwatches indexed by name of the code section /// private static Dictionary stopwatches = new Dictionary(); /// /// dictionary of the sum of runtimes indexed by name of the code section /// private static Dictionary sumTimes = new Dictionary(); /// /// used to prevent running , and simultaneously from different threads /// private static Object sync = new object(); /// /// Prints all collected timing information. /// public static void outputAll() { lock (sync) { StringBuilder divider = new StringBuilder(); divider.Append("├-"); divider.Append(new String('-', maxNameLength)); divider.Append("-┼-------┼-------┤"); Console.Clear(); Console.WriteLine(String.Format("| {0,-" + maxNameLength + "} | {1,-5} | {2,-5} |", "NAME", "AVG.", "CUR.")); Console.WriteLine(divider.ToString()); foreach (String name in stopwatches.Keys) { double average = sumTimes[name] / Math.Max(numTimes[name], 1); double current = currentTimes[name]; Console.WriteLine(String.Format("| {0,-" + maxNameLength + "} | {1:00.00} | {2:00.00} |", name, average, current)); } } } /// /// Starts a timer for the given name and initializes the dictionaries when called for the first time with this name. /// /// name of the code section public static void start(String name) { lock (sync) { if (!stopwatches.ContainsKey(name)) { stopwatches.Add(name, new Stopwatch()); minTimes.Add(name, int.MaxValue); maxTimes.Add(name, 0); sumTimes.Add(name, 0); numTimes.Add(name, 0); currentTimes.Add(name, 0); maxNameLength = Math.Max(maxNameLength, name.Length); } stopwatches[name].Restart(); } } /// /// Stops the timer for the given name and stores timing information. /// /// name of the code section public static void stop(String name) { lock (sync) { stopwatches[name].Stop(); double time = Math.Round((double)stopwatches[name].ElapsedTicks / (double)Stopwatch.Frequency * 1000.0, 2); if (time < minTimes[name]) minTimes[name] = time; if (time > maxTimes[name]) maxTimes[name] = time; sumTimes[name] += time; numTimes[name]++; currentTimes[name] = time; } } } }