From 694cca4b21878850ba6131105a0c560fdfbc5f10 Mon Sep 17 00:00:00 2001 From: Drachenkaetzchen Date: Wed, 15 Jan 2020 16:01:35 +0100 Subject: Added documentation for all performance counter methods and members. Refactored the naming of several members and methods to reflect their actual intention. --- .../PerformanceCounter/PerformanceCounter.cs | 99 +++++++++++----------- 1 file changed, 51 insertions(+), 48 deletions(-) (limited to 'src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs') diff --git a/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs index 3dbc693a..b2ec4c90 100644 --- a/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs +++ b/src/SMAPI/Framework/PerformanceCounter/PerformanceCounter.cs @@ -1,26 +1,32 @@ using System; -using System.Diagnostics; using System.Linq; using Cyotek.Collections.Generic; -using StardewModdingAPI.Framework.Utilities; namespace StardewModdingAPI.Framework.PerformanceCounter { internal class PerformanceCounter { + /// The size of the ring buffer. private const int MAX_ENTRIES = 16384; - public string Source { get; } - public static Stopwatch Stopwatch = new Stopwatch(); - public static long TotalNumEventsLogged; - public double MonitorThresholdMilliseconds { get; set; } - public bool Monitor { get; set; } + /// The collection to which this performance counter belongs. private readonly PerformanceCounterCollection ParentCollection; + /// The circular buffer which stores all performance counter entries private readonly CircularBuffer _counter; + /// The peak execution time private PerformanceCounterEntry? PeakPerformanceCounterEntry; + /// The name of the source. + public string Source { get; } + + /// The alert threshold in milliseconds + public double AlertThresholdMilliseconds { get; set; } + + /// If alerting is enabled or not + public bool EnableAlerts { get; set; } + public PerformanceCounter(PerformanceCounterCollection parentCollection, string source) { this.ParentCollection = parentCollection; @@ -28,90 +34,87 @@ namespace StardewModdingAPI.Framework.PerformanceCounter this._counter = new CircularBuffer(PerformanceCounter.MAX_ENTRIES); } - public void Reset() - { - this._counter.Clear(); - this.PeakPerformanceCounterEntry = null; - } - - public int GetAverageCallsPerSecond() - { - var x = this._counter.GroupBy( - p => - (int) p.EventTime.Subtract( - new DateTime(1970, 1, 1) - ).TotalSeconds); - - return x.Last().Count(); - } - + /// Adds a new performance counter entry to the list. Updates the peak entry and adds an alert if + /// monitoring is enabled and the execution time exceeds the threshold. + /// The entry to add. public void Add(PerformanceCounterEntry entry) { - PerformanceCounter.Stopwatch.Start(); this._counter.Put(entry); - if (this.Monitor && entry.Elapsed.TotalMilliseconds > this.MonitorThresholdMilliseconds) - { - this.ParentCollection.AddAlert(entry.Elapsed.TotalMilliseconds, this.MonitorThresholdMilliseconds, new AlertContext(this.Source, entry.Elapsed.TotalMilliseconds)); - } + if (this.EnableAlerts && entry.ElapsedMilliseconds > this.AlertThresholdMilliseconds) + this.ParentCollection.AddAlert(entry.ElapsedMilliseconds, this.AlertThresholdMilliseconds, + new AlertContext(this.Source, entry.ElapsedMilliseconds)); if (this.PeakPerformanceCounterEntry == null) - { this.PeakPerformanceCounterEntry = entry; - } else { - if (entry.Elapsed.TotalMilliseconds > this.PeakPerformanceCounterEntry.Value.Elapsed.TotalMilliseconds) - { + if (entry.ElapsedMilliseconds > this.PeakPerformanceCounterEntry.Value.ElapsedMilliseconds) this.PeakPerformanceCounterEntry = entry; - } } + } - PerformanceCounter.Stopwatch.Stop(); - PerformanceCounter.TotalNumEventsLogged++; + /// Clears all performance counter entries and resets the peak entry. + public void Reset() + { + this._counter.Clear(); + this.PeakPerformanceCounterEntry = null; } + /// Returns the peak entry. + /// The peak entry. public PerformanceCounterEntry? GetPeak() { return this.PeakPerformanceCounterEntry; } + /// Resets the peak entry. public void ResetPeak() { this.PeakPerformanceCounterEntry = null; } + /// Returns the last entry added to the list. + /// The last entry public PerformanceCounterEntry? GetLastEntry() { if (this._counter.IsEmpty) - { return null; - } + return this._counter.PeekLast(); } + /// Returns the average execution time of all entries. + /// The average execution time in milliseconds. public double GetAverage() { if (this._counter.IsEmpty) - { return 0; - } - return this._counter.Average(p => p.Elapsed.TotalMilliseconds); + return this._counter.Average(p => p.ElapsedMilliseconds); } - public double GetAverage(TimeSpan range) + /// Returns the average over a given time span. + /// The time range to retrieve. + /// The DateTime from which to start the average. Defaults to DateTime.UtcNow if null + /// The average execution time in milliseconds. + /// + /// The relativeTo parameter specifies from which point in time the range is subtracted. Example: + /// If DateTime is set to 60 seconds ago, and the range is set to 60 seconds, the method would return + /// the average between all entries between 120s ago and 60s ago. + /// + public double GetAverage(TimeSpan range, DateTime? relativeTo = null) { if (this._counter.IsEmpty) - { return 0; - } - var lastTime = this._counter.Max(x => x.EventTime); - var start = lastTime.Subtract(range); + if (relativeTo == null) + relativeTo = DateTime.UtcNow; + + DateTime start = relativeTo.Value.Subtract(range); - var entries = this._counter.Where(x => (x.EventTime >= start) && (x.EventTime <= lastTime)); - return entries.Average(x => x.Elapsed.TotalMilliseconds); + var entries = this._counter.Where(x => (x.EventTime >= start) && (x.EventTime <= relativeTo)); + return entries.Average(x => x.ElapsedMilliseconds); } } } -- cgit