我已经比较了.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());
}
Run Code Online (Sandbox Code Playgroud)
.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());
}
Run Code Online (Sandbox Code Playgroud)
基准测试执行1000次以计算获取对象的平均时间,以确保测试的可靠性.计时器是我使用的自定义计时器,任何计时器计数毫秒都应该这样做.
有趣的是,"myObject"有很多引用.如果涉及任何序列化,我就会理解为什么这个对象的性能不同(比如在分布式缓存中),但这些都是进程中的缓存,理论上应该可以在没有很多重大差异的情况下工作.
我正在研究开发一种应用程序,它将以每秒约2000行(帧)的速度处理来自线扫描相机的数据.对于这个实时应用程序,我觉得C/C++是要走的路.(这是我的感觉,其他人会同意托管代码不适合这项任务.)
不过,我已经做了非常少的MFC或任何其他的C++图形用户界面.不过,我真的很想做C#GUI.
所以我很自然地用C/C++编写数据密集型代码,用C#编写GUI.GUI将用于设置/校准/在线监控(并可能通过UDP输出数据,因为它在C#中更容易.
首先,我想看看是否有人同意这将是要走的路.根据我的编程经验(擅长低级C算法和高级C#GUI设计),感觉恰到好处.
其次,我不确定正确的方法.我只是在VS2005中汇总了一个解决方案,它从C#应用程序中调用了一些(extern"C")DLL函数.为了确保我能做到这一点,我写了DLL中的一些全局变量,并从中读取:
test.h
int globaldata;
extern "C" __declspec(dllexport) void set(int);
extern "C" __declspec(dllexport) int get();
Run Code Online (Sandbox Code Playgroud)
TEST.CPP
extern int data=0;
__declspec(dllexport) void set(int num) {
data = num;
}
__declspec(dllexport) int get() {
return data;
}
Run Code Online (Sandbox Code Playgroud)
test.cs中
[DllImport("test")]
private static extern void set(int num);
[DllImport("test")]
private static extern int get();
Run Code Online (Sandbox Code Playgroud)
调用get()并set()正常工作(get()返回我传递给的数字set()).
现在,我知道您也可以导出C++类,但它是否必须进行管理?这是如何运作的?我是以正确的方式来做这件事的吗?
感谢你的帮助!
*** EDIT ***
首先,感谢您迄今为止的精彩答案!我总是对Stack Overflow印象深刻......
我想我应该更多地关注一件事,不一定是原始速度(这可以是原型和基准测试).让我更关心的一件事是垃圾收集器的非确定性行为.这个应用程序将不会在执行垃圾收集宽容500ms的延迟.
我只是编写代码并在纯C#中尝试这个,但如果我提前知道GC和任何其他非确定性的.NET行为(?)会导致问题,我认为我的时间会更好地用于编码C/C++并找出最好的C#接口.
众所周知,秒表可能会在多线程异步应用程序中出现问题,该应用程序将在所有核心上运行.
在多处理器计算机上,线程运行在哪个处理器上并不重要.但是,由于BIOS或硬件抽象层(HAL)中的错误,您可以在不同的处理器上获得不同的时序结果.要指定线程的处理器关联,请使用ProcessThread.ProcessorAffinity方法.
有没有办法让我得到一些可靠的滴答/时间戳,比如具有高分辨率/准确度的值以及在cpu核心中是否一致?
如果不能使秒表(QueryPerformanceCounter)多核安全,那么在核心之间获得良好时间戳的下一个最佳方法是什么?DateTime.UtcNow.Ticks还是Environment.TickCount?还有其他柜台吗?
我确实需要比DateTime.UtcNow.Ticks更好的分辨率.(10-15ms)