Быстрое запоминание с помощью кортежей - PullRequest
3 голосов
/ 27 апреля 2020

Я хочу использовать мемоизацию для ускорения кода, похожего на (когда-либо вызывается только небольшое количество возможных значений аргументов):

double MyFun(double a,double b,int c,char d)
{
    double a = cpu_intensive_pure_function_1(a,c,d);
    double b = cpu_intensive_pure_function_2(b,c,d);
    return a+b;
}

Одна из возможностей - это обернуть аргументы в объект Tuple и используйте словарь (в новых версиях Do tnet хэширование кортежей сделано за вас)

Dictionary<Tuple<double,double,int,char>,double> MyFunCache = new Dictionary<Tuple<double,double,int,char>,double> ();
double MyFun(double a,double b,int c,char d)
{
    var tmp = Tuple<double,double,int,char>(a,b,c,d);
    if(MyFunCache.ContainsKey(tmp))
    {
         return MyFunCache[tmp];
    }

    double a = cpu_intensive_pure_function_1(a,c,d);
    double b = cpu_intensive_pure_function_2(b,c,d);
    return a+b;
}

Но для этого требуется создавать объект Tuple каждый раз, когда вызывается функция, которая кажется расточительной, разве нет лучшего способа ? Что-то уже содержит аргументы?

1 Ответ

1 голос
/ 27 апреля 2020

Вы можете использовать вместо ValueTuple. Также не забудьте обновить кэш, как только вы получите вычисленное значение:

Dictionary<(double,double,int,char) ,double> MyFunCache = new Dictionary<(double,double,int,char) ,double> ();
double MyFun(double a,double b,int c,char d)
{
    var key = (a,b,c,d);
    if(MyFunCache.TryGetValue(key, out var cachedResult))
    {
         return cachedResult;
    }

    double a = cpu_intensive_pure_function_1(a,c,d);
    double b = cpu_intensive_pure_function_2(b,c,d);

    MyFunCache.Add(key, a+ b);
    return a+b;
}
...