Saturday, August 28, 2010

A simple way to reduce memory usage of structs/enums in Dictionaries

I can't take credit for this tip, it was pointed out here.

As pointed out here, by default if you use a struct or an enum inside a dictionary, you will alloc objects every time you access the dictionary to box/unbox things. For example this will allocate both a Point an object to box it in:

var squareLookup = new Dictionary<Point, SkillSquare>()
squareLookup[new Point(0,0)] = null;

I ran into issues because I used something like this for drawing the skill tree, and when you scrolled we hit the dictionary a huge number of time.

The linked hint suggests doing something like:
public class PointEqualityComparer : IEqualityComparer<Point>
    {
        public static PointEqualityComparer Instance = new PointEqualityComparer();

        public bool Equals(Point x, Point y)
        {
            return x == y;
        }

        public int GetHashCode(Point obj)
        {
            return obj.GetHashCode();
        }
    }

var squareLookup = new Dictionary<Point, SkillSquare>
    (PointEqualityComparer.Instance)
squareLookup[new Point(0,0)] = null; 

With this simple change, a profiled run of scrolled went from over 70% of all allocated memory being Points to so few it wasn't even broken out as an entry. This increased performance by a huge amount.

No comments: