Added commands to enable and disable performance counters. Peak is now using the default interval

This commit is contained in:
Drachenkaetzchen 2020-01-21 12:20:06 +01:00
parent 84973ce572
commit 1b905205a3
5 changed files with 76 additions and 8 deletions

View File

@ -17,6 +17,8 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Other
{SubCommand.Detail, new[] {"detail", "d"}},
{SubCommand.Reset, new[] {"reset", "r"}},
{SubCommand.Trigger, new[] {"trigger"}},
{SubCommand.Enable, new[] {"enable"}},
{SubCommand.Disable, new[] {"disable"}},
{SubCommand.Examples, new[] {"examples"}},
{SubCommand.Concepts, new[] {"concepts"}},
{SubCommand.Help, new[] {"help"}},
@ -29,6 +31,8 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Other
Detail,
Reset,
Trigger,
Enable,
Disable,
Examples,
Help,
Concepts,
@ -69,6 +73,14 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Other
case SubCommand.Concepts:
this.OutputHelp(monitor, SubCommand.Concepts);
break;
case SubCommand.Enable:
SCore.PerformanceCounterManager.EnableTracking = true;
monitor.Log("Performance counter tracking is now enabled", LogLevel.Info);
break;
case SubCommand.Disable:
SCore.PerformanceCounterManager.EnableTracking = false;
monitor.Log("Performance counter tracking is now disabled", LogLevel.Info);
break;
case SubCommand.Help:
if (args.TryGet(1, "command", out string commandString))
this.OutputHelp(monitor, this.ParseCommandString(commandString));
@ -118,20 +130,20 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Other
StringBuilder sb = new StringBuilder();
TimeSpan peakSpan = TimeSpan.FromSeconds(60);
TimeSpan interval = TimeSpan.FromSeconds(60);
sb.AppendLine("Summary:");
sb.AppendLine($"Summary over the last {interval.TotalSeconds} seconds:");
sb.AppendLine(this.GetTableString(
data: data,
header: new[] {"Collection", "Avg Calls/s", "Avg Exec Time (Game)", "Avg Exec Time (Mods)", "Avg Exec Time (Game+Mods)", "Peak Exec Time (60s)"},
header: new[] {"Collection", "Avg Calls/s", "Avg Exec Time (Game)", "Avg Exec Time (Mods)", "Avg Exec Time (Game+Mods)", "Peak Exec Time"},
getRow: item => new[]
{
item.Name,
item.GetAverageCallsPerSecond().ToString(),
this.FormatMilliseconds(item.GetGameAverageExecutionTime(), threshold),
this.FormatMilliseconds(item.GetModsAverageExecutionTime(), threshold),
this.FormatMilliseconds(item.GetAverageExecutionTime(), threshold),
this.FormatMilliseconds(item.GetPeakExecutionTime(peakSpan), threshold)
this.FormatMilliseconds(item.GetGameAverageExecutionTime(interval), threshold),
this.FormatMilliseconds(item.GetModsAverageExecutionTime(interval), threshold),
this.FormatMilliseconds(item.GetAverageExecutionTime(interval), threshold),
this.FormatMilliseconds(item.GetPeakExecutionTime(interval), threshold)
},
true
));
@ -662,6 +674,8 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Other
sb.AppendLine(" detail|d Shows performance counter information for a given collection");
sb.AppendLine(" reset|r Resets the performance counters");
sb.AppendLine(" trigger Configures alert triggers");
sb.AppendLine(" enable Enables performance counter recording");
sb.AppendLine(" disable Disables performance counter recording");
sb.AppendLine(" examples Displays various examples");
sb.AppendLine(" concepts Displays an explanation of the performance counter concepts");
sb.AppendLine(" help Displays verbose help for the available commands");

View File

@ -133,7 +133,7 @@ namespace StardewModdingAPI.Framework.PerformanceCounter
DateTime start = relativeTo.Value.Subtract(range);
var entries = this._counter.Where(x => (x.EventTime >= start) && (x.EventTime <= relativeTo));
var entries = this._counter.Where(x => (x.EventTime >= start) && (x.EventTime <= relativeTo)).ToList();
if (!entries.Any())
return 0;

View File

@ -82,6 +82,15 @@ namespace StardewModdingAPI.Framework.PerformanceCounter
p.Key != Constants.GamePerformanceCounterName).Sum(p => p.Value.GetAverage());
}
/// <summary>Returns the average execution time for all non-game internal sources.</summary>
/// <param name="interval">The interval for which to get the average, relative to now</param>
/// <returns>The average execution time in milliseconds</returns>
public double GetModsAverageExecutionTime(TimeSpan interval)
{
return this.PerformanceCounters.Where(p =>
p.Key != Constants.GamePerformanceCounterName).Sum(p => p.Value.GetAverage(interval));
}
/// <summary>Returns the overall average execution time.</summary>
/// <returns>The average execution time in milliseconds</returns>
public double GetAverageExecutionTime()
@ -89,6 +98,14 @@ namespace StardewModdingAPI.Framework.PerformanceCounter
return this.PerformanceCounters.Sum(p => p.Value.GetAverage());
}
/// <summary>Returns the overall average execution time.</summary>
/// <param name="interval">The interval for which to get the average, relative to now</param>
/// <returns>The average execution time in milliseconds</returns>
public double GetAverageExecutionTime(TimeSpan interval)
{
return this.PerformanceCounters.Sum(p => p.Value.GetAverage(interval));
}
/// <summary>Returns the average execution time for game-internal sources.</summary>
/// <returns>The average execution time in milliseconds</returns>
public double GetGameAverageExecutionTime()
@ -99,6 +116,20 @@ namespace StardewModdingAPI.Framework.PerformanceCounter
return 0;
}
/// <summary>Returns the average execution time for game-internal sources.</summary>
/// <returns>The average execution time in milliseconds</returns>
public double GetGameAverageExecutionTime(TimeSpan interval)
{
if (this.PerformanceCounters.TryGetValue(Constants.GamePerformanceCounterName, out PerformanceCounter gameExecTime))
return gameExecTime.GetAverage(interval);
return 0;
}
/// <summary>Returns the peak execution time</summary>
/// <param name="interval">The interval for which to get the peak, relative to <paramref name="relativeTo"/></param>
/// <param name="relativeTo">The DateTime which the <paramref name="interval"/> is relative to, or DateTime.Now if not given</param>
/// <returns>The peak execution time</returns>
public double GetPeakExecutionTime(TimeSpan range, DateTime? relativeTo = null)
{
if (this.PeakInvocations.IsEmpty)

View File

@ -23,6 +23,9 @@ namespace StardewModdingAPI.Framework.PerformanceCounter
/// <summary>Specifies if alerts should be paused.</summary>
public bool PauseAlerts { get; set; }
/// <summary>Specifies if performance counter tracking should be enabled.</summary>
public bool EnableTracking { get; set; }
/// <summary>Constructs a performance counter manager.</summary>
/// <param name="monitor">The monitor for output logging.</param>
public PerformanceCounterManager(IMonitor monitor)
@ -49,6 +52,11 @@ namespace StardewModdingAPI.Framework.PerformanceCounter
/// <param name="collectionName">The collection name</param>
public void BeginTrackInvocation(string collectionName)
{
if (!this.EnableTracking)
{
return;
}
this.GetOrCreateCollectionByName(collectionName).BeginTrackInvocation();
}
@ -56,6 +64,11 @@ namespace StardewModdingAPI.Framework.PerformanceCounter
/// <param name="collectionName"></param>
public void EndTrackInvocation(string collectionName)
{
if (!this.EnableTracking)
{
return;
}
this.GetOrCreateCollectionByName(collectionName).EndTrackInvocation();
}
@ -65,6 +78,12 @@ namespace StardewModdingAPI.Framework.PerformanceCounter
/// <param name="action">The action to execute and track invocation time for.</param>
public void Track(string collectionName, string sourceName, Action action)
{
if (!this.EnableTracking)
{
action();
return;
}
DateTime eventTime = DateTime.UtcNow;
this.InvocationStopwatch.Reset();
this.InvocationStopwatch.Start();

View File

@ -15,6 +15,10 @@
<ApplicationIcon>icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>SMAPI_FOR_WINDOWS</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Cyotek.CircularBuffer" Version="1.0.2" />
<PackageReference Include="LargeAddressAware" Version="1.0.3" />