using System; using System.IO; using System.Diagnostics; using System.Collections.Generic; namespace Sog { public enum InnerPerfRecordId { MapPath = 1, Physics = 2, SyncActor= 3, } public class PerfStat { class recordOne { public int id; public string name; public long oneCallMaxTicks; public long oneCallMinTicks; public int callCount; public long totalTicks; public long startTick; //支持递归调用 public int recursion; public void Clear() { oneCallMaxTicks = 0; oneCallMinTicks = 0; callCount = 0; totalTicks = 0; startTick = 0; } } private const int IDMaxValue = 50; private string[] idNames = new string[IDMaxValue]; private Stopwatch _stopwatch; private recordOne[] records = new recordOne[IDMaxValue]; public void Start() { _stopwatch = new Stopwatch(); _stopwatch.Start(); } public void Register(int id, string name) { if(idNames[id] != null) { return; } idNames[id] = name; } public void ClearAll() { for (int i = 0; i < records.Length; i++) { var record = records[i]; if (record != null) { record.Clear(); } } _stopwatch.Restart(); } public void StartPerf(int id) { recordOne record = records[id]; if(record == null) { record = new recordOne() { id = id, name = idNames[id], callCount = 0, startTick = 0, oneCallMaxTicks = 0, oneCallMinTicks = long.MaxValue }; records[id] = record; } record.callCount++; record.recursion++; if (record.recursion == 1) { record.startTick = _stopwatch.ElapsedTicks; } } public void EndPerf(int id) { long ticks = _stopwatch.ElapsedTicks; recordOne record = records[id]; if (record == null) { return; } if(record.recursion == 0) { return; } record.recursion--; if(record.recursion == 0) { long thisCallTicks = ticks - record.startTick; record.totalTicks += thisCallTicks; if (thisCallTicks > record.oneCallMaxTicks) { record.oneCallMaxTicks = thisCallTicks; } if (thisCallTicks < record.oneCallMinTicks) { record.oneCallMinTicks = thisCallTicks; } } } public void LogAll(int logicMs) { long totalTicks = 0; for(int i= 0; i < records.Length; i++) { var record = records[i]; if (record != null) { if (record.id == 0) { totalTicks = record.totalTicks; } TraceLog.Debug("PerfStat.LogAll name {0,24} count {1,7} total {2,9} avg {3,10} max {4,10} min {5,10} percent {6,3}", record.name, record.callCount, record.totalTicks, record.totalTicks / record.callCount, record.oneCallMaxTicks, record.oneCallMinTicks, record.totalTicks * 1000 / totalTicks); } } double useTimeSecond = (double)totalTicks / Stopwatch.Frequency; double logicUseTimeSecond = (double)logicMs / 1000; TraceLog.Debug("PerfStat.LogAll logicTime {0:N3} cpuTime {1:N3} cpuFreq {2} LogLevel {3}" , logicUseTimeSecond, useTimeSecond, Stopwatch.Frequency, TraceLog.GetLogLevel()); } } }