.net system.runtime.caching 的性能
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3157340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Performance of system.runtime.caching
提问by Herber
I have compared the performance of system.runtime.caching in .NET 4.0 and the Enterprise Library Caching Block and to my surprise it performs terribly in comparison when fetching large data collections from cache items.
我比较了 .NET 4.0 和 Enterprise Library Caching Block 中 system.runtime.caching 的性能,令我惊讶的是,在从缓存项中获取大型数据集合时,它的性能非常糟糕。
Enterprise Library fetches 100 objects in about 0,15ms, 10000 objects in about 0,25ms. This is fast, and natural for an in-process cache because no data actually needs to be copied (only references).
企业库在大约 0.15 毫秒内获取 100 个对象,在大约 0.25 毫秒内获取 10000 个对象。这对于进程内缓存来说是快速且自然的,因为实际上不需要复制数据(仅引用)。
The .NET 4.0 caching fetches 100 objects in about 25ms, 10000 objects in about 1500ms! This is terribly slow in comparison and it makes me suspect the caching is done out-of-process.
.NET 4.0 缓存在大约 25 毫秒内获取 100 个对象,在大约 1500 毫秒内获取 10000 个对象!相比之下,这非常慢,这让我怀疑缓存是在进程外完成的。
Am I missing some configuration option, for example to enable in-process caching, or is the Enterprise Library Caching Block really this much faster?
我是否缺少一些配置选项,例如启用进程内缓存,或者企业库缓存块真的快得多吗?
Update
更新
Here's my benchmark:
这是我的基准:
First, I load the data from the database to the cache (separate from the benchmark).
首先,我将数据从数据库加载到缓存(与基准测试分开)。
I use a timer around the get methods to measure the time in milliseconds:
我在 get 方法周围使用一个计时器来测量以毫秒为单位的时间:
EnterpriseLibrary Caching
企业库缓存
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 Caching
.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());
}
The benchmark is executed 1000 times to compute average time to fetch the object to ensure reliability of the test. The timer is a custom timer I use, any timer counting milliseconds should do.
基准测试执行 1000 次以计算获取对象的平均时间,以确保测试的可靠性。计时器是我使用的自定义计时器,任何计数毫秒的计时器都应该做。
The interesting thing is that the "myObject" has numerous references. If there was any serialization involved I'd understand why the performance differs for this object (like in distributed caching), but these are both in-process caches that theoretically should work without many major differences at all.
有趣的是“myObject”有很多引用。如果涉及任何序列化,我会理解为什么此对象的性能不同(例如在分布式缓存中),但这些都是进程内缓存,理论上应该可以正常工作而没有太多主要差异。
回答by solublefish
My guess is that the details of your cache contents or policies are not the same. Without seeing the setup, or the inserts, it's hard to say exactly how.
我的猜测是您的缓存内容或策略的详细信息不一样。没有看到设置或插入物,很难说到底是怎么做的。
Regardless, the two libraries have different performance characteristics, and which one is better clearly depends on the situation.
无论如何,这两个库具有不同的性能特征,哪个更好显然取决于具体情况。
Probably my test (code below) is too simple to be representative, but with it running on my machine, MemoryCache is roughly 10x faster.
可能我的测试(下面的代码)太简单了,无法代表,但它在我的机器上运行,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>

