169 lines
4.4 KiB
C#
169 lines
4.4 KiB
C#
#if ZEN_INTERNAL_PROFILING
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using ModestTree;
|
|
|
|
namespace Zenject
|
|
{
|
|
// Similar to ProfileBlock except used for measuring speed of zenject specifically
|
|
// And does not use unity's profiler
|
|
public static class ProfileTimers
|
|
{
|
|
static Dictionary<string, TimerInfo> _timers = new Dictionary<string, TimerInfo>();
|
|
|
|
public static void ResetAll()
|
|
{
|
|
foreach (var timer in _timers.Values)
|
|
{
|
|
timer.Reset();
|
|
}
|
|
}
|
|
|
|
public static string FormatResults()
|
|
{
|
|
var result = new StringBuilder();
|
|
|
|
// Uncomment if you only want to see zenject related info
|
|
//var timers = _timers.Where(x => x.Key != "User Code");
|
|
var timers = _timers;
|
|
|
|
var total = timers.Select(x => x.Value.TotalMilliseconds).Sum();
|
|
|
|
result.Append("Total time tracked: {0:0.00} ms. Details:".Fmt(total));
|
|
|
|
foreach (var pair in timers.OrderByDescending(x => x.Value.TotalMilliseconds))
|
|
{
|
|
var time = pair.Value.TotalMilliseconds;
|
|
var percent = 100.0 * (time / total);
|
|
var name = pair.Key;
|
|
|
|
result.Append("\n {0:00.0}% ({1:00000}x) ({2:0000} ms) {3}".Fmt(percent, pair.Value.CallCount, time, name));
|
|
}
|
|
|
|
return result.ToString();
|
|
}
|
|
|
|
public static double GetTimerElapsedMilliseconds(string name)
|
|
{
|
|
return _timers[name].TotalMilliseconds;
|
|
}
|
|
|
|
public static IDisposable CreateTimedBlock(string name)
|
|
{
|
|
TimerInfo timer;
|
|
|
|
if (!_timers.TryGetValue(name, out timer))
|
|
{
|
|
timer = new TimerInfo();
|
|
_timers.Add(name, timer);
|
|
}
|
|
|
|
timer.CallCount++;
|
|
|
|
if (timer.IsRunning)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return TimedBlock.Pool.Spawn(timer);
|
|
}
|
|
|
|
class TimedBlock : IDisposable
|
|
{
|
|
public static StaticMemoryPool<TimerInfo, TimedBlock> Pool =
|
|
new StaticMemoryPool<TimerInfo, TimedBlock>(OnSpawned, OnDespawned);
|
|
|
|
readonly List<TimerInfo> _pausedTimers = new List<TimerInfo>();
|
|
|
|
TimerInfo _exclusiveTimer;
|
|
|
|
static void OnSpawned(
|
|
TimerInfo exclusiveTimer, TimedBlock instance)
|
|
{
|
|
Assert.That(instance._pausedTimers.Count == 0);
|
|
|
|
instance._exclusiveTimer = exclusiveTimer;
|
|
|
|
foreach (var timer in _timers.Values)
|
|
{
|
|
if (exclusiveTimer == timer)
|
|
{
|
|
Assert.That(!timer.IsRunning);
|
|
timer.Resume();
|
|
}
|
|
else if (timer.IsRunning)
|
|
{
|
|
timer.Pause();
|
|
instance._pausedTimers.Add(timer);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void OnDespawned(TimedBlock instance)
|
|
{
|
|
Assert.That(instance._exclusiveTimer.IsRunning);
|
|
instance._exclusiveTimer.Pause();
|
|
|
|
foreach (var timer in instance._pausedTimers)
|
|
{
|
|
Assert.That(!timer.IsRunning);
|
|
timer.Resume();
|
|
}
|
|
|
|
instance._pausedTimers.Clear();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Pool.Despawn(this);
|
|
}
|
|
}
|
|
|
|
public class TimerInfo
|
|
{
|
|
readonly Stopwatch _timer;
|
|
|
|
public TimerInfo()
|
|
{
|
|
_timer = new Stopwatch();
|
|
}
|
|
|
|
public int CallCount
|
|
{
|
|
get; set;
|
|
}
|
|
|
|
public double TotalMilliseconds
|
|
{
|
|
get { return _timer.Elapsed.TotalMilliseconds; }
|
|
}
|
|
|
|
public bool IsRunning
|
|
{
|
|
get { return _timer.IsRunning; }
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
_timer.Reset();
|
|
}
|
|
|
|
public void Resume()
|
|
{
|
|
_timer.Start();
|
|
}
|
|
|
|
public void Pause()
|
|
{
|
|
_timer.Stop();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|