system.runtime.caching的性能

时间:2010-07-01 11:37:34

标签: .net performance caching .net-4.0 enterprise-library

我已经比较了.NET 4.0中的system.runtime.caching和企业库缓存块的性能,令我惊讶的是,当从缓存项中获取大数据集时,它的性能非常可观。

Enterprise Library在大约0,15ms内获取100个对象,在大约0.25ms内获取10000个对象。这对于进程内缓存来说是快速且自然的,因为实际上不需要复制数据(仅引用)。

.NET 4.0缓存在大约25毫秒内获取100个对象,在大约1500毫秒内获取10000个对象!相比之下,这非常慢,这让我怀疑缓存是在进程外完成的。

我是否缺少一些配置选项,例如启用进程内缓存,还是企业库缓存块真的这么快?

更新

这是我的基准:

首先,我将数据从数据库加载到缓存(与基准分开)。

我在get方法周围使用一个计时器来测量时间,以毫秒为单位:

EnterpriseLibrary缓存

Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager _cache;

public void InitCache(){
    _cache = CacheFactory.GetCacheManager("myCacheName");
}

public void Benchmark(){
    HighPerformanceTimer timer = new HighPerformanceTimer();
    timer.Start();
    myObject o = (myObject)_cache.GetData(myCacheKey);
    timer.Stop();
    Response.Write(timer.GetAsStringInMilliseconds());
}

.NET 4.0缓存

    System.Runtime.Caching.MemoryCache _cache;

    public void InitCache(){
        _cache = new MemoryCache("myCacheName");
    }

    public void Benchmark(){
        HighPerformanceTimer timer = new HighPerformanceTimer();
        timer.Start();
        myObject o = (myObject)_cache.Get(myCacheKey);
        timer.Stop();
        Response.Write(timer.GetAsStringInMilliseconds());
    }

基准测试执行1000次以计算获取对象的平均时间,以确保测试的可靠性。计时器是我使用的自定义计时器,任何计时器计数毫秒都应该这样做。

有趣的是,“myObject”有很多引用。如果涉及任何序列化,我就会理解为什么这个对象的性能不同(比如分布式缓存),但这些都是进程中的缓存,理论上应该没有很多重大差异。

1 个答案:

答案 0 :(得分:8)

我的猜测是你的缓存内容或政策的细节不一样。如果没有看到设置或插入,很难确切地说明如何。

无论如何,这两个库具有不同的性能特征,哪一个更好地取决于具体情况。

可能我的测试(下面的代码)过于简单而无法代表,但随着它在我的机器上运行,MemoryCache大约是10倍更快

class Program
{        
    const string myCacheKey = "foo";
    static ICacheManager _elCache;        
    static MemoryCache _rtCache;
    public static void InitCache()
    {            
        _elCache = CacheFactory.GetCacheManager();
        _elCache.Add(myCacheKey, new object());

        _rtCache = new MemoryCache("cache");
        _rtCache.Add(myCacheKey, new object(), new CacheItemPolicy());
    }
    public static string ElBenchmark(int n)
    {
        Stopwatch timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < n; i++)
        {
            object o = _elCache.GetData(myCacheKey);
        }
        timer.Stop();
        return timer.ElapsedTicks.ToString();
    }
    public static string RtBenchmark(int n)
    {
        Stopwatch timer = new Stopwatch();
        timer.Start();
        for (int i = 0; i < n; i++)
        {
            object o = _rtCache.Get(myCacheKey);
        }
        timer.Stop();
        return timer.ElapsedTicks.ToString();
    }
    static void Main(string[] args)
    {
        while (true)
        {
            InitCache();
            StringBuilder sb = new StringBuilder();
            System.Diagnostics.Debug.Write("EL: " + ElBenchmark(10000));
            System.Diagnostics.Debug.Write("\t");
            System.Diagnostics.Debug.Write("RT: " + RtBenchmark(10000));
            System.Diagnostics.Debug.Write("\r\n");
        }
    }
}


<?xml version="1.0"?>
<configuration>

  <configSections>
    <section name="cachingConfiguration"
         type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <cachingConfiguration defaultCacheManager="MyCacheManager">
    <cacheManagers>
      <add name="MyCacheManager" type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
       expirationPollFrequencyInSeconds="60"
       maximumElementsInCacheBeforeScavenging="50000"
       numberToRemoveWhenScavenging="1000"
       backingStoreName="NullBackingStore" />
    </cacheManagers>
    <backingStores>
      <add type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
       name="NullBackingStore" />
    </backingStores>
  </cachingConfiguration>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>  
</configuration>