【发布时间】:2020-04-27 11:49:39
【问题描述】:
我想使用 memoization 来加速看起来类似于(只有少数可能的参数值被调用)的代码:
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;
}
一种可能性是将 args 包装到 Tuple 对象中并使用 Dictionary(新版本的 Dotnet 已为您完成元组散列)
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 对象,这似乎很浪费,难道没有更好的方法吗?有什么东西已经在争论了吗?
【问题讨论】:
-
我相信您已经在使用一种非常有效(且可读)的方式。与“CPU 密集型功能”相比,分配和比较元组对性能的影响应该可以忽略不计。
-
@TripleAccretion 虽然“缓存”是有效的通用术语,但此问题中描述的纯函数的特殊情况通常称为"memoization"。此外,
Tuple比较的实现本身应该已经在处理哈希冲突,所以这应该不是问题。 -
如果您使用
ValueTuple,那么您将不会受到内存分配的影响。 -
另一件事:它确实有助于分析受影响的功能,看看某些操作是否具有可衡量的性能影响。只有当这种影响很大时,才需要进行优化。
-
这个词是memoization,不是memorization。
标签: c# tuples memoization