diff --git a/isometric-park-fna/FNAGame.cs b/isometric-park-fna/FNAGame.cs --- a/isometric-park-fna/FNAGame.cs +++ b/isometric-park-fna/FNAGame.cs @@ -63,6 +63,7 @@ TimeSpan updateTime = TimeSpan.Zero; Queue past_fps = new Queue(100); + Queue past_draw = new Queue(100); int tilesDrawn = 0; private static int width = 1280; @@ -866,10 +867,12 @@ #region debug_window //Calcs for debug window: + past_draw.Enqueue(this.drawTime); if ((this.frameCounter % 15) == 0) { past_fps.Enqueue(this.frameRate); + /* if (this.frameRate > 60.0) { @@ -937,6 +940,24 @@ additionalInfo.Add("Dialog entries", entries); additionalInfo.Add("Metadata entries", descriptions); + if (past_fps.Count() > 5) { + additionalInfo.Add(".01%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.0001f).ToString()); + additionalInfo.Add(".1%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.001f).ToString()); + additionalInfo.Add("1%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.01f).ToString()); + additionalInfo.Add("50%% fps", MathUtils.Percentile(past_fps.Skip(5).ToArray(), 0.50f).ToString()); + } + + if (past_draw.Count() > 5) { + var past_draw_floats = past_draw.Skip(5).Select(ts => ts.TotalMilliseconds).ToArray(); + additionalInfo.Add(".01%% draw", MathUtils.Percentile(past_draw_floats, 0.0001f).ToString()); + additionalInfo.Add(".1%% draw", MathUtils.Percentile(past_draw_floats, 0.001f).ToString()); + additionalInfo.Add("1%% draw", MathUtils.Percentile(past_draw_floats, 0.01f).ToString()); + additionalInfo.Add("50%% draw", MathUtils.Percentile(past_draw_floats, 0.50f).ToString()); + additionalInfo.Add("99%% draw", MathUtils.Percentile(past_draw_floats, 0.99f).ToString()); + additionalInfo.Add("99.9%% draw", MathUtils.Percentile(past_draw_floats, 0.999f).ToString()); + additionalInfo.Add("99.99%% draw", MathUtils.Percentile(past_draw_floats, 0.9999f).ToString()); + } + debugWindow.Layout(debugInfo, additionalInfo, ref show_another_window); _imGuiRenderer.AfterLayout(); diff --git a/isometric-park-fna/Utils/MathUtils.cs b/isometric-park-fna/Utils/MathUtils.cs --- a/isometric-park-fna/Utils/MathUtils.cs +++ b/isometric-park-fna/Utils/MathUtils.cs @@ -1,6 +1,15 @@ using System; +using JM.LinqFaster; namespace isometricparkfna { + public class EmptyArrayException : Exception { + public EmptyArrayException() { + } + + public EmptyArrayException(string message) : base(message) { + } + + } public class MathUtils { public MathUtils() @@ -126,5 +135,39 @@ return integers[index]; } + + public static float Percentile(float[] floats, float percentile) { + if (floats.Length > 0) { + Array.Sort(floats); + var raw_position = (floats.Length-1) * percentile; + + var lower_position = (int)raw_position; + var higher_position = Math.Min((int)(raw_position+1), floats.Length-1); + + var remainder = (raw_position % 1); + + return (floats[lower_position] * (1-remainder)) + (floats[higher_position] * remainder); + } + else { + throw new EmptyArrayException("Array must not be empty"); + } + } + + public static double Percentile(double[] doubles, double percentile) { + if (doubles.Length > 0) { + Array.Sort(doubles); + var raw_position = (doubles.Length-1) * percentile; + + var lower_position = (int)raw_position; + var higher_position = Math.Min((int)raw_position + 1, doubles.Length -1); + + var remainder = (raw_position % 1); + + return (doubles[lower_position] * (1-remainder)) + (doubles[higher_position] * remainder); + } + else { + throw new EmptyArrayException("Array must not be empty"); + } + } } }