diff options
author | Drachenkaetzchen <felicia@drachenkatze.org> | 2020-01-10 01:27:56 +0100 |
---|---|---|
committer | Drachenkaetzchen <felicia@drachenkatze.org> | 2020-01-10 01:27:56 +0100 |
commit | a751252c4ee3b48977d5d24c36a4e4e5466f93db (patch) | |
tree | 6de90dd8c6a5199fa49c84a9a089dda29a1758d6 /src/SMAPI/Framework/Utilities | |
parent | ceff27c9a82bb16358aa0f390ce3f346c06c47bc (diff) | |
download | SMAPI-a751252c4ee3b48977d5d24c36a4e4e5466f93db.tar.gz SMAPI-a751252c4ee3b48977d5d24c36a4e4e5466f93db.tar.bz2 SMAPI-a751252c4ee3b48977d5d24c36a4e4e5466f93db.zip |
Initial commit of the performance counters
Diffstat (limited to 'src/SMAPI/Framework/Utilities')
4 files changed, 144 insertions, 0 deletions
diff --git a/src/SMAPI/Framework/Utilities/EventPerformanceCounterCategory.cs b/src/SMAPI/Framework/Utilities/EventPerformanceCounterCategory.cs new file mode 100644 index 00000000..14f74317 --- /dev/null +++ b/src/SMAPI/Framework/Utilities/EventPerformanceCounterCategory.cs @@ -0,0 +1,16 @@ +namespace StardewModdingAPI.Framework.Utilities +{ + public class EventPerformanceCounterCategory + { + public IPerformanceCounterEvent Event { get; } + public double MonitorThreshold { get; } + public bool IsImportant { get; } + public bool Monitor { get; } + + public EventPerformanceCounterCategory(IPerformanceCounterEvent @event, bool isImportant) + { + this.Event = @event; + this.IsImportant = isImportant; + } + } +} diff --git a/src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs b/src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs new file mode 100644 index 00000000..55302f90 --- /dev/null +++ b/src/SMAPI/Framework/Utilities/IPerformanceCounterEvent.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace StardewModdingAPI.Framework.Utilities +{ + public interface IPerformanceCounterEvent + { + string GetEventName(); + long GetAverageCallsPerSecond(); + IDictionary<string, PerformanceCounter> PerformanceCounters { get; } + + double GetGameAverageExecutionTime(); + double GetModsAverageExecutionTime(); + double GetAverageExecutionTime(); + } +} diff --git a/src/SMAPI/Framework/Utilities/PerformanceCounter.cs b/src/SMAPI/Framework/Utilities/PerformanceCounter.cs new file mode 100644 index 00000000..c9ffcf5b --- /dev/null +++ b/src/SMAPI/Framework/Utilities/PerformanceCounter.cs @@ -0,0 +1,102 @@ +using System; +using System.Diagnostics; +using System.Linq; +using Cyotek.Collections.Generic; + +namespace StardewModdingAPI.Framework.Utilities +{ + public class PerformanceCounter + { + private const int MaxCount = 16384; + + public string Name { get; } + public static Stopwatch Stopwatch = new Stopwatch(); + public static long EventsLogged; + + + private readonly CircularBuffer<PerformanceCounterEntry> _counter; + + private PerformanceCounterEntry? PeakPerformanceCounterEntry; + + public PerformanceCounter(string name) + { + this.Name = name; + this._counter = new CircularBuffer<PerformanceCounterEntry>(PerformanceCounter.MaxCount); + } + + public int GetAverageCallsPerSecond() + { + var x = this._counter.GroupBy( + p => + (int) p.EventTime.Subtract( + new DateTime(1970, 1, 1) + ).TotalSeconds); + + return x.Last().Count(); + } + + public void Add(PerformanceCounterEntry entry) + { + PerformanceCounter.Stopwatch.Start(); + this._counter.Put(entry); + + if (this.PeakPerformanceCounterEntry == null) + { + this.PeakPerformanceCounterEntry = entry; + } + else + { + if (entry.Elapsed.TotalMilliseconds > this.PeakPerformanceCounterEntry.Value.Elapsed.TotalMilliseconds) + { + this.PeakPerformanceCounterEntry = entry; + } + } + + PerformanceCounter.Stopwatch.Stop(); + EventsLogged++; + } + + public PerformanceCounterEntry? GetPeak() + { + return this.PeakPerformanceCounterEntry; + } + + public void ResetPeak() + { + this.PeakPerformanceCounterEntry = null; + } + + public PerformanceCounterEntry? GetLastEntry() + { + if (this._counter.IsEmpty) + { + return null; + } + return this._counter.PeekLast(); + } + + public double GetAverage() + { + if (this._counter.IsEmpty) + { + return 0; + } + + return this._counter.Average(p => p.Elapsed.TotalMilliseconds); + } + + public double GetAverage(TimeSpan range) + { + if (this._counter.IsEmpty) + { + return 0; + } + + var lastTime = this._counter.Max(x => x.EventTime); + var start = lastTime.Subtract(range); + + var entries = this._counter.Where(x => (x.EventTime >= start) && (x.EventTime <= lastTime)); + return entries.Average(x => x.Elapsed.TotalMilliseconds); + } + } +} diff --git a/src/SMAPI/Framework/Utilities/PerformanceCounterEntry.cs b/src/SMAPI/Framework/Utilities/PerformanceCounterEntry.cs new file mode 100644 index 00000000..8e156a32 --- /dev/null +++ b/src/SMAPI/Framework/Utilities/PerformanceCounterEntry.cs @@ -0,0 +1,10 @@ +using System; + +namespace StardewModdingAPI.Framework.Utilities +{ + public struct PerformanceCounterEntry + { + public DateTime EventTime; + public TimeSpan Elapsed; + } +} |