Created
September 10, 2017 10:31
-
-
Save noisecrime/493d2cdb549286b5298984bc0f95f129 to your computer and use it in GitHub Desktop.
StopWatchProfiler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
#if UNITY_5_5_OR_NEWER | |
using Profiler = UnityEngine.Profiling.Profiler; | |
#endif | |
public class StopWatchProfiler : MonoBehaviour | |
{ | |
public struct ProfilerMemoryPacket | |
{ | |
public long monoHeap; | |
public long monoUsed; | |
public long memoryAllocated; | |
public long memoryReserved; | |
} | |
public class ProfilerPacket | |
{ | |
public long startTime; | |
public long totalTime; | |
public int totalCalls; | |
public ProfilerMemoryPacket memoryOnEnter; | |
public ProfilerMemoryPacket memoryOnExit; | |
} | |
public static Dictionary<string, ProfilerPacket> m_PofilerPackets = new Dictionary<string, ProfilerPacket>(); | |
public static List<string> m_FiLoWatchnames = new List<string>(); | |
public static Stopwatch m_Stopwatch = new Stopwatch(); | |
public static int m_HasMatchngPairs = 0; | |
void Start() | |
{ | |
StartCoroutine( EndOfFrame() ); | |
} | |
IEnumerator EndOfFrame() | |
{ | |
while ( true ) | |
{ | |
NewFrame(); | |
yield return new WaitForEndOfFrame(); | |
} | |
} | |
#region ENTRY POINTS | |
// Called from scripts to begin or end both custom stopwatch profiling and Unity Profiling. | |
[Conditional( "DEVELOPMENT_BUILD" ), Conditional( "UNITY_EDITOR" )] | |
public static void BeginSample( string name ) | |
{ | |
BeginWatch(name); | |
Profiler.BeginSample(name); | |
} | |
[Conditional( "DEVELOPMENT_BUILD" ), Conditional( "UNITY_EDITOR" )] | |
public static void EndSample() | |
{ | |
EndWatch(); | |
Profiler.EndSample(); | |
} | |
#endregion | |
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | |
private static void NewFrame() | |
{ | |
if(m_HasMatchngPairs != 0) UnityEngine.Debug.LogError("StopWatchProfiler: A Begin has no matching End"); | |
m_PofilerPackets.Clear(); | |
m_FiLoWatchnames.Clear(); | |
m_Stopwatch.Reset(); | |
m_Stopwatch.Start(); | |
m_HasMatchngPairs = 0; | |
} | |
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | |
private static void BeginWatch( string name ) | |
{ | |
ProfilerPacket pp; | |
if ( m_PofilerPackets.TryGetValue( name, out pp ) == false ) | |
{ | |
pp = new ProfilerPacket(); | |
m_PofilerPackets.Add( name, pp); | |
} | |
pp.startTime = m_Stopwatch.ElapsedMilliseconds; | |
#if UNITY_5_5_OR_NEWER | |
pp.memoryOnEnter.monoHeap = Profiler.GetMonoHeapSizeLong(); // reserved system memory that Mono is using for allocations | |
pp.memoryOnEnter.monoUsed = Profiler.GetMonoUsedSizeLong(); // amount of allocated memory for non collected objects in Mono | |
pp.memoryOnEnter.memoryAllocated = Profiler.GetTotalAllocatedMemoryLong(); // amount of allocated and used system memory | |
pp.memoryOnEnter.memoryReserved = Profiler.GetTotalReservedMemoryLong(); // amount of reserved system memory | |
// pp.memoryOnEnter.memTexture = Profiler.GetRuntimeMemorySize(); // runtime memory usage of the resource | |
#else | |
pp.memoryOnEnter.monoHeap = Profiler.GetMonoHeapSize(); // reserved system memory that Mono is using for allocations | |
pp.memoryOnEnter.monoUsed = Profiler.GetMonoUsedSize(); // amount of allocated memory for non collected objects in Mono | |
pp.memoryOnEnter.memoryAllocated = Profiler.GetTotalAllocatedMemory(); // amount of allocated and used system memory | |
pp.memoryOnEnter.memoryReserved = Profiler.GetTotalReservedMemory(); // amount of reserved system memory | |
#endif | |
m_FiLoWatchnames.Add( name ); | |
m_HasMatchngPairs++; | |
// UnityEngine.Debug.LogFormat( "BeginWatch: {0} Time: {1} Calls: {2}", name, pp.startTime, pp.totalCalls); | |
} | |
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] | |
private static void EndWatch() | |
{ | |
m_HasMatchngPairs--; | |
if ( m_FiLoWatchnames.Count - 1 < 0 ) | |
{ | |
UnityEngine.Debug.LogError( "StopWatchProfiler: End has no Begin!" ); | |
return; | |
} | |
string name = m_FiLoWatchnames[ m_FiLoWatchnames.Count - 1]; | |
ProfilerPacket pp; | |
if ( m_PofilerPackets.TryGetValue( name, out pp ) == true ) | |
{ | |
pp.totalTime += m_Stopwatch.ElapsedMilliseconds - pp.startTime; | |
pp.totalCalls += 1; | |
#if UNITY_5_5_OR_NEWER | |
pp.memoryOnExit.monoHeap = Profiler.GetMonoHeapSizeLong(); // reserved system memory that Mono is using for allocations | |
pp.memoryOnExit.monoUsed = Profiler.GetMonoUsedSizeLong(); // amount of allocated memory for non collected objects in Mono | |
pp.memoryOnExit.memoryAllocated = Profiler.GetTotalAllocatedMemoryLong(); // amount of allocated and used system memory | |
pp.memoryOnExit.memoryReserved = Profiler.GetTotalReservedMemoryLong(); // amount of reserved system memory | |
// pp.memoryOnEnter.memTexture = Profiler.GetRuntimeMemorySize(); // runtime memory usage of the resource | |
#else | |
pp.memoryOnExit.monoHeap = Profiler.GetMonoHeapSize(); // reserved system memory that Mono is using for allocations | |
pp.memoryOnExit.monoUsed = Profiler.GetMonoUsedSize(); // amount of allocated memory for non collected objects in Mono | |
pp.memoryOnExit.memoryAllocated = Profiler.GetTotalAllocatedMemory(); // amount of allocated and used system memory | |
pp.memoryOnExit.memoryReserved = Profiler.GetTotalReservedMemory(); // amount of reserved system memory | |
#endif | |
// UnityEngine.Debug.LogFormat( "EndWatch: {0} Time: {1} Calls: {2}", name, pp.totalTime, pp.totalCalls); | |
} | |
m_FiLoWatchnames.RemoveAt(m_FiLoWatchnames.Count - 1); | |
} | |
#if DEVELOPMENT_BUILD || UNITY_EDITOR | |
// "{0} Ms: {1:d4} Calls: {2:d2} Heap: {3}/{4} Used: {5}/{6} Allocated: {7}/{8} Reserved: {9}/{10}\n") | |
public static string GetResults( string format = "{0} Ms: {1:d4} Calls: {2:d2} Mem: {5,4:F1}/{6,4:F1}\n") | |
{ | |
m_Stopwatch.Stop(); | |
// if( !UnityEngine.Debug.isDebugBuild ) return "NOT DEVELOPMENT BUILD"; | |
if( m_HasMatchngPairs != 0) UnityEngine.Debug.LogError("StopWatchProfiler: A Begin has no matching End"); | |
if( m_PofilerPackets.Count == 0) return ( "No Results"); | |
string str = ""; | |
double bytesToMegaBytes = 1024.0 * 1024.0; | |
foreach (KeyValuePair<string, ProfilerPacket> pair in m_PofilerPackets) | |
{ | |
double deltaHeap = ( (long) pair.Value.memoryOnExit.monoHeap - (long) pair.Value.memoryOnEnter.monoHeap); | |
double deltaUsed = ( (long) pair.Value.memoryOnExit.monoUsed - (long) pair.Value.memoryOnEnter.monoUsed); | |
double deltaAllocated = ( (long) pair.Value.memoryOnExit.memoryAllocated - (long) pair.Value.memoryOnEnter.memoryAllocated); | |
double deltaReserved = ( (long) pair.Value.memoryOnExit.memoryReserved - (long) pair.Value.memoryOnEnter.memoryReserved); | |
str += string.Format | |
( | |
format, | |
pair.Key, pair.Value.totalTime/pair.Value.totalCalls, pair.Value.totalCalls, | |
deltaHeap/bytesToMegaBytes, pair.Value.memoryOnExit.monoHeap/bytesToMegaBytes, | |
deltaUsed/bytesToMegaBytes, pair.Value.memoryOnExit.monoUsed/bytesToMegaBytes, | |
deltaAllocated/bytesToMegaBytes, pair.Value.memoryOnExit.memoryAllocated/bytesToMegaBytes, | |
deltaReserved/bytesToMegaBytes, pair.Value.memoryOnExit.memoryReserved/bytesToMegaBytes | |
); | |
} | |
return str; | |
} | |
#else | |
public static string GetResults() | |
{ | |
return "NOT DEVELOPMENT BUILD"; | |
} | |
#endif | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment