扩展方法的缓存结果

时间:2013-08-12 16:38:59

标签: c# caching optimization extension-methods

我感兴趣的是一种缓存/存储在任意对象上执行的扩展方法的结果的方法。

意图是避免多余的昂贵操作。以此扩展方法为例,将整数转换为包含其数字的整数数组。请忽略对方法本身的潜在优化......这不是我关注的问题。

    public static int[] Digits(this int i)
    {
        List<int> n = new List<int>();

        for (; i > 0; i /= 10)
            n.Add(i % 10);

        n.Reverse();
        return n.ToArray();
    }

如果在同一对象上调用该方法两次,则必须执行两次。我的第一种方法是缓存结果并检查对象的相等性:

static class Extensions
{
    public static int[] Digits(this int i)
    {
        int[] cache;
        if (ExtensionCache.IsIntegerDigitized(i, out cache))
            return cache;

        List<int> n = new List<int>();

        for (; i > 0; i /= 10)
            n.Add(i % 10);

        n.Reverse();

        ExtensionCache.CacheIntegerDigitization(i, n.ToArray());

        return n.ToArray();
    }
}

static class ExtensionCache
{
    static Dictionary<int, int[]> _digitizedIntegerCache;
    public static Dictionary<int, int[]> DigitizedIntegerCache
    {
        get { return _digitizedIntegerCache ?? (_digitizedIntegerCache = new Dictionary<int, int[]>()); }
    }

    static public bool IsIntegerDigitized(int i, out int[] digits)
    {
        if (DigitizedIntegerCache.ContainsKey(i))
        {
            digits = DigitizedIntegerCache[i];
            return true;
        }
        else
        {
            digits = null;
            return false;
        }
    }

    static public void CacheIntegerDigitization(int i, int[] digits)
    {

        if (DigitizedIntegerCache.ContainsKey(i))
            return; 

        DigitizedIntegerCache.Add(i, digits);
    }
}

我预见到的最大问题是不断增长的缓存结果字典和未经检查的内存消耗。我不想在超出范围的对象上保留结果缓存。

在这个例子中,我使用了int,一个值类型,但是我对一个涵盖引用和值类型的解决方案很感兴趣。

1 个答案:

答案 0 :(得分:2)

您可以考虑使用MemoryCache,而不是编写自己的缓存类。它能够根据绝对或滑动时间窗口限制内存使用或删除缓存项目。