From b7b878835440cd085f7978ac434a8795c55ebdf6 Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Sun, 20 Oct 2024 16:55:02 +0200 Subject: [PATCH] Optimize ZwinderStateManger.GetStateClosestToFrame AllStates() sorted the returned states, but this order was not used anywhere else, so I've removed it. GetStateClosestToFrame is solvable in O(n), so sorting is not required there either. This is an O(n log(n)) -> O(n) improvement that is mostly relevant for the state history integrity checker --- .../movie/tasproj/ZwinderStateManager.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs index 31cb2ce487..ba12abd5c2 100644 --- a/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs +++ b/src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs @@ -251,14 +251,13 @@ namespace BizHawk.Client.Common } /// - /// Enumerate all states in reverse order + /// Enumerate all states in the following order: current -> recent -> gap -> reserved states /// internal IEnumerable AllStates() { return CurrentAndRecentStates() .Concat(GapStates()) - .Concat(ReservedStates()) - .OrderByDescending(s => s.Frame); + .Concat(ReservedStates()); } public int Last => StateCache.Max(); @@ -474,8 +473,15 @@ namespace BizHawk.Client.Common if (frame < 0) throw new ArgumentOutOfRangeException(nameof(frame)); - var si = AllStates().First(s => s.Frame <= frame); - return new KeyValuePair(si.Frame, si.Read()); + StateInfo closestState = null; + foreach (var state in AllStates()) + { + if (state.Frame <= frame && (closestState is null || state.Frame > closestState.Frame)) + { + closestState = state; + } + } + return new KeyValuePair(closestState!.Frame, closestState.Read()); } public bool HasState(int frame)