ace/Source/ACE.Common/RateMonitor.cs
Mag-nus 118c890285 More profiling based improvements (#1067)
* RateMonitor created

* NetworkSession Update foreach change to help profiling

This just removes the lambda pattern for the foreach so profilers can monitor each line individually.

Functionality is unchanged.

* Reduce Landblock ctor async work to a single thread

This helps reduce ACE thread starvation

* NetworkSession cosmetic

* NetworkSession cosmetic

* NetworkSession currentBundles ConcurrentDictionary to Array

This significantly improves the performance of NetworkSession.

Arrays are faster than Dictionaries, and we manage concurrency to the elements via currentBundleLocks.

We're also able to get away with using an array because the number of elements is only 12.

Accessing the indexes of currentBundles should be atomic as it's an array of reference values, compiled as 64 bit.

* Add InParallel to database functions that do their underlying work in parallel

* DoSessionWork tick outbound messages in series, not in parallel.

* NetworkSession should not be interfacing with ActionChains

* Don't load landblock ctor resources in parallel

Save the threads in the pool for more important work

* LandblockManager removed check/recheck

This is legacy code from a pattern no longer used. It is no longer required.

* Cosmetic
2018-10-15 23:06:54 -04:00

74 lines
1.9 KiB
C#

using System.Diagnostics;
namespace ACE.Common
{
public class RateMonitor
{
private readonly Stopwatch stopwatch = new Stopwatch();
/// <summary>
/// Last event duration in seconds
/// </summary>
public double LastEvent { get; private set; }
public long TotalEvents { get; private set; }
public double TotalSeconds { get; private set; }
/// <summary>
/// Longest event duration in seconds
/// </summary>
public double LongestEvent { get; private set; }
/// <summary>
/// Shortest event duration in seconds
/// </summary>
public double ShortestEvent { get; private set; }
/// <summary>
/// Average event duration in seconds
/// </summary>
public double AverageEventDuration => TotalSeconds / TotalEvents;
public void RegisterEventStart()
{
stopwatch.Reset();
stopwatch.Start();
}
/// <summary>
/// returns the elapsed seconds for this event
/// </summary>
public double RegisterEventEnd()
{
stopwatch.Stop();
LastEvent = stopwatch.Elapsed.TotalSeconds;
TotalEvents++;
TotalSeconds += LastEvent;
if (LastEvent > LongestEvent)
LongestEvent = LastEvent;
if (LastEvent < ShortestEvent)
ShortestEvent = LastEvent;
return LastEvent;
}
public void ClearEventHistory()
{
LastEvent = 0;
TotalEvents = 0;
TotalSeconds = 0;
LongestEvent = 0;
ShortestEvent = 0;
}
public override string ToString()
{
return $"Total Events: {TotalEvents:N0}, Average: {AverageEventDuration:N4} s, Longest: {LongestEvent:N4} s, Shortest: {ShortestEvent:N4} s, Last: {LastEvent:N4} s";
}
}
}