mirror of https://github.com/ppy/osu
Add statistics display for `MemoryCachingComponent`s
Never sure if these are working as they should (or how well they are working). This helps quite a bit.
This commit is contained in:
parent
7053a8507b
commit
a1b6ec60c8
|
@ -8,7 +8,9 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Extensions.TypeExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Statistics;
|
||||
|
||||
namespace osu.Game.Database
|
||||
{
|
||||
|
@ -20,8 +22,16 @@ public abstract class MemoryCachingComponent<TLookup, TValue> : Component
|
|||
{
|
||||
private readonly ConcurrentDictionary<TLookup, TValue> cache = new ConcurrentDictionary<TLookup, TValue>();
|
||||
|
||||
private readonly GlobalStatistic<MemoryCachingStatistics> statistics;
|
||||
|
||||
protected virtual bool CacheNullValues => true;
|
||||
|
||||
protected MemoryCachingComponent()
|
||||
{
|
||||
statistics = GlobalStatistics.Get<MemoryCachingStatistics>(nameof(MemoryCachingComponent<TLookup, TValue>), GetType().ReadableName());
|
||||
statistics.Value = new MemoryCachingStatistics();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the cached value for the given lookup.
|
||||
/// </summary>
|
||||
|
@ -30,12 +40,20 @@ public abstract class MemoryCachingComponent<TLookup, TValue> : Component
|
|||
protected async Task<TValue> GetAsync([NotNull] TLookup lookup, CancellationToken token = default)
|
||||
{
|
||||
if (CheckExists(lookup, out TValue performance))
|
||||
{
|
||||
statistics.Value.HitCount++;
|
||||
return performance;
|
||||
}
|
||||
|
||||
var computed = await ComputeValueAsync(lookup, token).ConfigureAwait(false);
|
||||
|
||||
statistics.Value.MissCount++;
|
||||
|
||||
if (computed != null || CacheNullValues)
|
||||
{
|
||||
cache[lookup] = computed;
|
||||
statistics.Value.Usage = cache.Count;
|
||||
}
|
||||
|
||||
return computed;
|
||||
}
|
||||
|
@ -51,6 +69,8 @@ protected void Invalidate(Func<TLookup, bool> matchKeyPredicate)
|
|||
if (matchKeyPredicate(kvp.Key))
|
||||
cache.TryRemove(kvp.Key, out _);
|
||||
}
|
||||
|
||||
statistics.Value.Usage = cache.Count;
|
||||
}
|
||||
|
||||
protected bool CheckExists([NotNull] TLookup lookup, out TValue value) =>
|
||||
|
@ -63,5 +83,31 @@ protected bool CheckExists([NotNull] TLookup lookup, out TValue value) =>
|
|||
/// <param name="token">An optional <see cref="CancellationToken"/> to cancel the operation.</param>
|
||||
/// <returns>The computed value.</returns>
|
||||
protected abstract Task<TValue> ComputeValueAsync(TLookup lookup, CancellationToken token = default);
|
||||
|
||||
private class MemoryCachingStatistics
|
||||
{
|
||||
/// <summary>
|
||||
/// Total number of cache hits.
|
||||
/// </summary>
|
||||
public int HitCount;
|
||||
|
||||
/// <summary>
|
||||
/// Total number of cache misses.
|
||||
/// </summary>
|
||||
public int MissCount;
|
||||
|
||||
/// <summary>
|
||||
/// Total number of cached entities.
|
||||
/// </summary>
|
||||
public int Usage;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
int totalAccesses = HitCount + MissCount;
|
||||
double hitRate = totalAccesses == 0 ? 0 : (double)HitCount / totalAccesses;
|
||||
|
||||
return $"i:{Usage} h:{HitCount} m:{MissCount} {hitRate:0%}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue