gpt4 book ai didi

c# - 缓存函数结果

转载 作者:太空狗 更新时间:2023-10-29 20:12:12 26 4
gpt4 key购买 nike

为了好玩,我正在使用一个类来轻松缓存函数结果。基本思想是您可以采用任何您想要的函数——尽管您只想将它​​用于相对昂贵的函数——并轻松地将它包装起来以使用相对便宜的字典查找,以便以后使用相同的参数运行。真的没什么:

public class AutoCache<TKey, TValue> 
{
public AutoCache(Func<TKey, TValue> FunctionToCache)
{
_StoredFunction = FunctionToCache;
_CachedData = new Dictionary<TKey, TValue>();
}

public TValue GetResult(TKey Key)
{
if (!_CachedData.ContainsKey(Key))
_CachedData.Add(Key, _StoredFunction(Key));
return _CachedData[Key];
}

public void InvalidateKey(TKey Key)
{
_CachedData.Remove(Key);
}

public void InvalidateAll()
{
_CachedData.Clear();
}

private Dictionary<TKey, TValue> _CachedData;
private Func<TKey, TValue> _StoredFunction;
}

不幸的是,有一些额外的限制使它的用处大大降低。我们还可以添加一些功能和其他实现注意事项。我正在寻找关于可以针对以下任何一点进行改进的方法的想法:

  • 这需要一个针对给定参数集返回相同结果的函数(它必须是无状态的)。可能没有办法改变这一点。
  • 它仅限于非常狭窄的代表范围。我们能否将它扩展为轻松地用于任何接受至少一个参数并返回一个值的函数,也许通过将参数包装在匿名类型中?或者我们是否需要为我们想要支持的每个 Func 委托(delegate)进行额外的实现?如果是这样,我们是否可以构建一个抽象类来简化此操作?
  • 它不是线程安全的。
  • 没有自动失效。这使得垃圾收集变得危险。您需要将其保存一段时间才能发挥作用,这意味着您不会真正丢弃旧的和可能不需要的缓存项。
  • 我们能否从中继承,使缓存在函数只有一个参数的情况下是双向的?

作为引用,如果我曾经在实际代码中使用过它,我认为它最有可能的地方是作为业务逻辑层的一部分,我在其中使用此代码在数据访问层中包装一个方法,该方法只是拉取来自查找表的数据。在这种情况下,数据库之旅相对于字典来说会很昂贵,而且几乎总是只有一个“键”值用于查找,所以这是一个很好的匹配。

最佳答案

这种自动缓存函数结果的另一个名称是内存。对于公共(public)接口(interface),请考虑以下方面:

public Func<T,TResult> Memoize<T,TResult>(Func<T,TResult> f)

...并简单地使用多态性将 T 存储在对象字典中。

扩展委托(delegate)范围可以通过柯里化(Currying)和偏函数应用来实现。像这样:

static Func<T1,Func<T2,TResult>> Curry(Func<T1,T2,TResult> f)
{
return x => y => f(x, y);
}
// more versions of Curry

由于 Curry 将多参数函数转换为单参数函数(但可能返回函数),因此返回值本身符合内存条件。

另一种方法是使用反射来检查委托(delegate)类型,并将元组存储在字典中,而不是简单地存储参数类型。一个简单的元组将只是一个数组包装器,其哈希码和相等逻辑使用深度比较和哈希。

弱引用可以帮助无效化,但是使用 WeakReference 键创建字典是棘手的 - 最好在运行时的支持下完成(WeakReference 值更容易)。我相信那里有一些实现。

线程安全很容易通过在突变事件的内部字典上锁定来实现,但是拥有一个无锁字典可能会提高高并发场景下的性能。该词典可能更难创建 - 有一个有趣的 presentation on one for Java here虽然。

关于c# - 缓存函数结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1166677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com