/* * ============================================================================== * Filename: LuaExport * Created: 2018/7/13 14:29:22 * Author: エル・プサイ・コングリィ * Purpose: * ============================================================================== */ #if UNITY_EDITOR using System; using System.Collections.Generic; using UnityEngine; using UnityEditorInternal; namespace MikuLuaProfiler { public class LuaProfiler { private static IntPtr _mainL = IntPtr.Zero; public static IntPtr mainL { get { return _mainL; } set { _mainL = value; } } public static string GetLuaMemory() { long result = 0; if (mainL != IntPtr.Zero) { try { result = LuaLib.GetLuaMemory(mainL); } catch { } } return GetMemoryString(result); } //开始采样时候的lua内存情况,因为中间有可能会有二次采样,所以要丢到一个盏中 //public static readonly List beginSampleMemoryStack = new List(); public static readonly Stack beginSampleMemoryStack = new Stack(); private static Action m_SampleEndAction; private static bool isDeep { get { #if UNITY_EDITOR return ProfilerDriver.deepProfiling; #else return false; #endif } } public static void SetSampleEnd(Action action) { m_SampleEndAction = action; } private static int m_currentFrame = 0; public static void BeginSample(IntPtr luaState, string name) { if (m_currentFrame != Time.frameCount) { PopAllSampleWhenLateUpdate(); m_currentFrame = Time.frameCount; } #if DEBUG long memoryCount = LuaLib.GetLuaMemory(luaState); Sample sample = Sample.Create(Time.realtimeSinceStartup, memoryCount, name); //beginSampleMemoryStack.Add(sample); beginSampleMemoryStack.Push(sample); #endif } public static void PopAllSampleWhenLateUpdate() { for (int i = 0, imax = beginSampleMemoryStack.Count; i < imax; i++) { //var item = beginSampleMemoryStack[i]; var item = beginSampleMemoryStack.Pop(); if (item.fahter == null) { item.Restore(); } } beginSampleMemoryStack.Clear(); } public static void EndSample(IntPtr luaState) { #if DEBUG if (beginSampleMemoryStack.Count <= 0) { return; } int count = beginSampleMemoryStack.Count; //Sample sample = beginSampleMemoryStack[beginSampleMemoryStack.Count - 1]; Sample sample = beginSampleMemoryStack.Pop(); long oldMemoryCount = sample.currentLuaMemory; //beginSampleMemoryStack.RemoveAt(count - 1); long nowMemoryCount = LuaLib.GetLuaMemory(luaState); //sample.fahter = count > 1 ? beginSampleMemoryStack[count - 2] : null; sample.fahter = count > 1 ? beginSampleMemoryStack.Pop() : null; if (!isDeep) { long delta = nowMemoryCount - oldMemoryCount; long tmpDelta = delta; foreach(var item in beginSampleMemoryStack) { item.currentLuaMemory += tmpDelta; } //for (int i = 0, imax = beginSampleMemoryStack.Count; i < imax; i++) //{ // Sample s = beginSampleMemoryStack[i]; // s.currentLuaMemory += tmpDelta; // beginSampleMemoryStack[i] = s; //} } sample.costTime = Time.realtimeSinceStartup - sample.currentTime; var gc = nowMemoryCount - sample.realCurrentLuaMemory; sample.costGC = gc > 0 ? gc : 0; if (m_SampleEndAction != null && beginSampleMemoryStack.Count == 0) { m_SampleEndAction(sample); } //释放掉被累加的Sample if (beginSampleMemoryStack.Count != 0 && sample.fahter == null) { sample.Restore(); } #endif } const long MaxB = 1024; const long MaxK = MaxB * 1024; const long MaxM = MaxK * 1024; const long MaxG = MaxM * 1024; public static string GetMemoryString(long value, string unit = "B") { string result = null; if (value < MaxB) { result = string.Format("{0}{1}", value, unit); } else if (value < MaxK) { result = string.Format("{0:N2}K{1}", (float)value / MaxB, unit); } else if (value < MaxM) { result = string.Format("{0:N2}M{1}", (float)value / MaxK, unit); } else if (value < MaxG) { result = string.Format("{0:N2}G{1}", (float)value / MaxM, unit); } return result; } } } #endif