Adam Coffman

I write code, sometimes well.

Generic Function Memoization in C#

| Comments

Most competent developers have used memoization at some point in their career whether they have known it by name or not. Essentially, it is a technique for caching the results of function calls to improve performance by eliminating the need for repeated calculations. This can be as simple as using a dictionary or hash table to store the results of each call, and then checking that table before calling the function. The other day, I was looking for a way to encapsulate this logic into a reusable form. The following is what I came up with. Its not perfect, but it takes the form of an extension method for any function that accepts one argument and returns a non-void value. If you need to use a more complicated set of arguments, you can always declare a quick class to encapsulate them. In a more dynamic language, there would be better ways to do this - but this seemed like a decent solution for C#.

1
2
3
4
5
6
7
8
9
10
11
public static class Memoization {
  public static Func<T,K> MemoizeFunction<T,K>( this Func<T, K> function ) {
    var table = new Dictionary<T, K>();
      return ( args ) => {
        if ( table.ContainsKey( args ) ) return table[args];
        var result = function( args );
        table[args] = result;
        return result;
      };
   }
}

You could use this function to wrap any other function with memoization logic as follows

1
2
3
4
5
6
7
8
9
10
11
12
//Assuming you had an existing function with the following definition:
//public int Square(int num);

Func<int,int> memoizedSquare = (arg) => Square(arg);

memoizedSquare = memoizedSquare.Memoize();

//first time the function is evaluated
memoizedSquare(2);

//second time the value will be pulled from the dictionary instead
memoizedSquare(2);

After showing this to a coworker he directed me to a pretty old blog post detailing an almost identical technique, while I developed this function on my own - I will link to his more thourough explanation here

Comments