You can reduce the memory footprint by using BitVector32
instead of bool
. A bool
in .NET occupies a full word in memory. A BitVector32
allows you to store the equivalent of 32 bools the same memory space.
By replacing all of the bool
fields in State
with a single BitVector32
, I was able to reduce State
's memory footprint from 68 bytes to 12 (as measured by Marshal.SizeOf<State>()
). Since State
is the key in the dictionary, that adds up to a decent reduction in memory usage overall.
After applying my changes to your master
branch and running for 1,000,000 steps, the memory usage of the state dictionary dropped from ~215 MB to ~167 MB (as measured by the Visual Studio profiler). After 5,000,000 steps, it dropped from ~864 MB to ~671 MB.
You could push this technique even further by packing numeric values into bit vectors. There are some examples of doing so in the docs.
Here's a sample of the code that I used. All of the changes happened within State
. I opted for the most convenient refactoring path... there might be a more efficient/performant way to code all this.
BitVector32 bits;
private const int ReinforcedIndexFingerMask = 1 << 0;
private const int CarpalTunnelPreventionCreamMask = 1 << 1;
public bool ReinforcedIndexFinger
{
get => bits[ReinforcedIndexFingerMask];
set => bits[ReinforcedIndexFingerMask] = value;
}
public bool CarpalTunnelPreventionCream
{
get => bits[CarpalTunnelPreventionCreamMask];
set => bits[CarpalTunnelPreventionCreamMask] = value;
}
```
As an added bonus, I think you could simplify the GetHashCode()
and Equals()
implementations by comparing the bit vector directly, rather than comparing every value individually.