【问题标题】:What's the neatest way to add memoization to a package library将备忘录添加到包库的最简洁方法是什么
【发布时间】:2019-10-09 16:47:49
【问题描述】:

假设(完全假设;))我有 nuget 包,它本质上公开了一组静态扩展方法:

public static class MyNugetLibrary
{
    public static int DoSomethingExpensiveAndUseful(this string input)
    {
        return input.Length;
    }

    public static int DoSomethingElseExpensiveAndUseful(this string input)
    {
        return (int)input.ToCharArray().First();
    }
}

而且,出于理智的原因,我得出结论,这个包真正需要的是缓存。给定输入,输出是恒定的,输入是原始的。

在我的情况下,输出改变是不可能的,所以我永远不必担心缓存失效等问题。

如果只有 1 或 2 个方法,我可以将私有静态 Dictionary 添加到扩展类,并在方法中向字典询问答案。

但我很想不要重复那么多代码,而且有一个非常好的 memoize 函数:

public static Func<T, TResult> Memoize<T, TResult>(this Func<T, TResult> f)
{
    var cache = new ConcurrentDictionary<T, TResult>();
    return a => cache.GetOrAdd(a, f);
}

(从这里被盗:https://www.aleksandar.io/post/memoization/

但我不太清楚如何使用该方法来记忆这些功能,而无需更改我的包的外部接口。

我该怎么做?


如果我们可以进一步这样做,最终用户 (MyNugetLibrary.DisableCaching()) 可以禁用缓存以防他们担心,例如内存占用。

【问题讨论】:

  • 对于那些希望赢得无限互联网积分的人,另请参阅此处:stackoverflow.com/questions/56269443/… 并找出一种在一个解决方案中实现这两个目标的方法 :)
  • 忽略为每个记忆动作创建字典实例的效率方面,是什么阻止您使用本文中描述的这种方法?

标签: c# nuget-package memoization


【解决方案1】:

你可以使用 Fody/MethodCache

运行

Install-Package Fody
Install-Package MethodCache.Fody

然后您可以将方法更改为:

public interface ICache
{
    bool Contains(string key);
    T Retrieve<T>(string key);
    void Store(string key, object data);
    void Remove(string key);
}

public static class MyNugetLibrary
{
    public static ICache Cache { get; set; } = DefaultCache;

    public readonly static ICache DefaultCache = new MemoryCache();
    public readonly static ICache NoCache = new UnCache();
    [Cache]
    public static int DoSomethingExpensiveAndUseful(this string input)
    {
        return input.Length;
    }
    [Cache]
    public static int DoSomethingElseExpensiveAndUseful(this string input)
    {
        return (int)input.ToCharArray().First();
    }
}

【讨论】:

  • 嗯,如果我愿意为代码库添加大量复杂性 (Fody),这看起来是一个非常好的解决方案。但我更喜欢更明确的编码方法,如果有的话。如果几天后没有提供其他解决方案,我会接受这个(如果我忘记了,请随时联系我!)。
  • @Brondahl Fody 将零复杂度添加到您的代码库中。它是一种 Post Compile IL Weaving 技术。
  • 对不起,“代码库”可能是错误的术语......“库”/“包”。目前我的整个程序包只有几十行代码,任何想要使用它的人都可以打开并立即阅读,并准确了解它的工作原理和方式。如果有人非常关心最小化传递依赖关系,那么将 Fody 添加到它是“我的项目到底添加了什么”的复杂性的一大步
  • 很公平。但是,一般来说,您的问题是关于面向方面的编程,以及如何以最小的影响将 Memoize 方面添加到您的代码中。有关该主题的更多阅读,refer to my answer on the topic.
猜你喜欢
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 2017-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多