解决方案
你只能memoize的一个函数,如果所有输入是值类型或不可改变的基准类型,如果返回值类型或新的实例基准类型,并且如果没有副作用。期。
性记忆化取决于一个确定性的映射之间的输入和输出。每次呼叫 F(a, b, c)
在其中的a、b和c包含相同的价值观必须返回相同的结果,以便为性记忆化是可能的。
如果一个参数的基准类型,那么,即使其价值并没有改变,多个电话的功能利用可能会产生不同的结果。一个简单的例子:
public int MyFunction(MyType t)
{
return t.Value;
}
Console.WriteLine(MyFunction(t));
t.Value++;
Console.WriteLine(MyFunction(t));
同样,如果一个功能取决于一个值外,那么多个电话这功能用同样的参数可以返回不同的结果:
int Value = 0;
public int MyFunction(int input)
{
return Value;
}
Console.WriteLine(MyFunction(1));
Value++;
Console.WriteLine(MyFunction(1));
天帮你,如果你memoized功能并不比其他的东西值返回或新的基准类型:
int Value = 0;
public int MyFunction(int input)
{
Value++;
return input;
}
如果你把这叫功能的10倍, Value
将10.如果你重构使用性记忆化然后叫它10倍, Value
将1.
你可以开始走下去的道路,如何memoize状态,这样就可以假了一个函数,memoizes引用类型。但什么您真正地memoizing是一套价值观的工作。你可以同样破解memoized功能有的副作用,使其副作用之前发生性记忆化.但这是乞讨的麻烦。
如果要实现性记忆化成功,需要一个基准类型,恰当的做法是"重构"的部分的功能,只能对价值的类型,并memoize这一职能,例如:
public int MyFunction(MyType t)
{
return t.Value + 1;
}
这样的:
public int MyFunction(MyType t)
{
return MyMemoizableFunction(t.Value);
}
private int MyMemoizableFunction(int value)
{
return value + 1;
}
任何其他方法来实现性记忆化,你把a)做同样的事情,通过比较模糊的手段,或者b)不会的工作。
其他提示
嗯,任何功能,从理论上说,是一个候选人性记忆化.然而,记得性记忆化是所有关于空间交易的速度-
在一般情况下,这意味着,更多的国家功能要求或者取决于为了计算答案,较高的空间成本,降低了是否可以memoize的方法。
您的两个例子都是基本的情况下,更多的国家将需要保存。这有两个副作用。
首先,这将需要更多的存储空间以memoize的功能,由于更多的信息将需要保存。
第二,这可能会减慢memoized功能,因为较大的空间,成本较高的查询的答复,以及更高的成本在寻找是否有结果之前保存。
在一般情况下,我倾向于仅仅考虑的功能,有几个可能的投入和低储存要求,除非有一个非常高的成本计算的回答。
我acknoledge,这是模糊的,但这是部分的"艺术性",在建筑。有没有"正确"的答案没有实现这两个选项(memozied和非memoized职能)、分析和测量。
你已经拥有想到的方式来提供一个AOP解决方案提供性记忆化周围的功能 Foo
, 什么还剩下图?
是的,你可以通过一个目的是任意的复杂性作为参数,一memoized功能,只要它是不可改变的,因为所有的事情它取决。再次,这是不容易发现静态的时刻。
你仍然坚持这个想法,你可以静态检查代码为了提醒你的用户在这个问题:"这是一个很好的想法的适用性记忆化的功能 Foo
?"
如果你让你的要求,你们将加入一个全球研究努力,已经持续了许多年来为止。取决于如何的雄心勃勃的,你是的,我猜。