Two argument Memoization

后端 未结 5 2085
既然无缘
既然无缘 2021-01-06 07:48

In C# how do I memoize a function with two arguments?

Do I have to curry before memoization?

Wes Dyer wrote the Memoization code I typically use, but now I n

相关标签:
5条回答
  • 2021-01-06 08:19

    I also did some work on memoization in C#. My results are similar but use a dictionary key derived from the concatenation of the input object hash codes. The pattern can be extended to as many intputs as Func<> will allow.

    Se more here: http://bit.ly/t6iNJP

    0 讨论(0)
  • 2021-01-06 08:27

    With new versions of .NET you can simplify the accepted solution's code a bit by using tuples

        public static Func<TParam1, TParam2, TReturn> Memoize<TParam1, TParam2, TReturn>(Func<TParam1, TParam2, TReturn> func)
        {
            var map = new Dictionary<Tuple<TParam1, TParam2>, TReturn>();
            return (param1, param2) =>
            {
                var key = Tuple.Create(param1, param2);
                TReturn result;
                if (!map.TryGetValue(key, out result))
                {
                    result = func(param1, param2);
                    map.Add(key, result);
                }
                return result;
            };
        }
    
    0 讨论(0)
  • 2021-01-06 08:27

    You should be able to memoize a pair. The two arg function calls a single arg function that you memoize.

    0 讨论(0)
  • 2021-01-06 08:36

    Wes has another post where he gives a two (or more) argument version of Memoize. It does not require a custom comparer.

    0 讨论(0)
  • 2021-01-06 08:38

    You just make an overloaded version of the Memoize method that has three generic types and takes a function with two parameters, and the two arguments. It still returns a parameterless function:

    public static Func<R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, A1 a1, A2 a2)
    {
      R value = default(R);
      bool hasValue = false;
      return () =>
        {
          if (!hasValue)
          {
            hasValue = true;
            value = f(a1,a2);
          }
          return value;
        };
    }
    

    Edit:
    Alternatively, you need to make a custom IEqualityComparer for a KeyValuePair that contains the two arguments, for the Memoize method to be able to return a function with two parameters:

    public static Func<A1,A2,R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, IEqualityComparer<KeyValuePair<A1,A2>> comparer)
    {
       var map = new Dictionary<KeyValuePair<A1,A2>,R>(comparer);
       return (a1,a2) =>
          {
             R value;
             KeyValuePair<A1,A2> key = new KeyValuePair<A1,A2>(a1,a2);
             if (map.TryGetValue(key, out value)) {
                return value;
             }
             value = f(a1,a2);
             map.Add(key, value);
             return value;
          };
    }
    
    0 讨论(0)
提交回复
热议问题