2010-07-01 26 views
28

我已經比較了.NET 4.0中的system.runtime.caching和企業庫緩存塊的性能,我驚訝地發現,從緩存項中獲取大數據集合時,它的性能會非常差。system.runtime.caching的性能

企業庫在大約0,15ms內獲取100個對象,在大約0,25ms內獲取10000個對象。這對於進程內高速緩存來說是快速和自然的,因爲實際上不需要複製任何數據(只有引用)。

.NET 4.0緩存在大約25ms內獲取100個對象,在大約1500ms內獲取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」有大量的參考文獻。如果涉及到任何序列化,我會理解爲什麼此對象的性能不同(如分佈式緩存),但這些都是進程內緩存,理論上應該沒有太多重大差異。

+0

您使用MemoryCache還是基準測試自己的實現?根據msdn MemoryCache isprocess。 – ata 2010-07-01 12:06:47

+0

我正在使用MemoryCache,沒有任何特定的配置。 – Herber 2010-07-01 12:22:31

+0

你能告訴我們你的基準嗎? – 2010-07-01 12:33:39

回答

8

我的猜測是你的緩存內容或策略的細節是不一樣的。沒有看到設置或插入,很難說清楚。

無論如何,這兩個庫有不同的性能特徵,哪一個更好取決於具體情況。

也許我的測試(代碼如下)太簡單了,沒有代表性,但是運行在我的機器上,MemoryCache大概是10x 更快

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>