Skip to content

Commit

Permalink
Optimize ZwinderStateManger.GetStateClosestToFrame
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Morilli committed Oct 20, 2024
1 parent 7ab2ca6 commit b7b8788
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions src/BizHawk.Client.Common/movie/tasproj/ZwinderStateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,13 @@ private IEnumerable<StateInfo> ReservedStates()
}

/// <summary>
/// Enumerate all states in reverse order
/// Enumerate all states in the following order: current -> recent -> gap -> reserved states
/// </summary>
internal IEnumerable<StateInfo> AllStates()
{
return CurrentAndRecentStates()
.Concat(GapStates())
.Concat(ReservedStates())
.OrderByDescending(s => s.Frame);
.Concat(ReservedStates());
}

public int Last => StateCache.Max();
Expand Down Expand Up @@ -474,8 +473,15 @@ public KeyValuePair<int, Stream> GetStateClosestToFrame(int frame)
if (frame < 0)
throw new ArgumentOutOfRangeException(nameof(frame));

var si = AllStates().First(s => s.Frame <= frame);
return new KeyValuePair<int, Stream>(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<int, Stream>(closestState!.Frame, closestState.Read());
}

public bool HasState(int frame)
Expand Down

0 comments on commit b7b8788

Please sign in to comment.