简体   繁体   English

像C#中的数据结构一样,缓存的最佳结构?

[英]Best structure for cache like data structure in C#?

this was more a conceptual question, but I was wondering what the best C# data structure is for a cache like structure. 这是一个概念上的问题,但是我想知道对于像缓存这样的结构来说,最佳的C#数据结构是什么。 I'll explain what I'm looking for. 我会解释我在寻找什么。

I'm making a game that uses sprites for graphics. 我正在制作一个使用精灵图形的游戏。 Sprites are based on Images (SFML library images, not standard C# images, but I don't think that really matters). Sprite基于图像(SFML库图像,而不是标准C#图像,但我认为这并不重要)。 These images need to be loaded from a file on disk, and this can get costly (time wise) when many sprites need to be created in rapid succession. 这些图像需要从磁盘上的文件中加载,并且当需要快速连续创建许多精灵时,这样做可能会增加成本(在时间上)。 To reduce some of this load time, I want to make use of a cahce like structure to store the images files, and when they were last updated (I'll be using this update time to determine when to evict stuff from the cache). 为了减少一些加载时间,我想使用类似cahce的结构来存储图像文件以及它们的最后更新时间(我将使用此更新时间来确定何时从缓存中删除内容)。 The cache will be indexed using a combination of the sprite name and a few other details. 高速缓存将使用精灵名称和其他一些详细信息的组合进行索引。 this index will map to a structure like below: 该索引将映射到如下结构:

struct ImageEntry
{
    Image image;
    TickCount lastupdate;
    TickCount evictionTime;
}

When the game requests a sprite, the request will be issued to a content manager who will look for a match in the cache structure. 当游戏请求精灵时,该请求将发布给内容管理员,后者将在缓存结构中寻找匹配项。 If a match is found, a structure like above will be found. 如果找到匹配项,则将找到上述结构。 The content manager will use the image to make the sprite, then update the lastupdate time to the time the structure was called. 内容管理器将使用图像制作精灵,然后将lastupdate时间更新为调用该结构的时间。 If a match is not found, a new strucut will be made and the image loaded from the image file (and used to make the sprite). 如果找不到匹配项,将创建一个新的结构,并从图像文件中加载图像(并用于制作精灵)。 The lastupdate time will be set to the current time. 最后更新时间将设置为当前时间。 eviction time is set based on a predefined constant, or an optional component in the request. 驱逐时间是基于预定义常量或请求中的可选组件设置的。

Now heres what I need to do: periodically, I need to run through the whole cache, compare each struct's lastupdate to the current game time. 现在,这里是我需要做的:定期,我需要遍历整个缓存,将每个结构的lastupdate与当前游戏时间进行比较。 If the different between those two is greater then the eviction time, I want to evict the struct entry from the cache. 如果两者之间的差异大于收回时间,我想从缓存中逐出struct条目。 Additionally, if a sprite request issues a new struct, and the size of the cache is greater then a predefined value, I need to find the least recently updated struct and evict it to make room for the new struct. 另外,如果一个sprite请求发出一个新的结构,并且缓存的大小大于预定义的值,那么我需要找到更新最少的结构并将其逐出以为新结构腾出空间。

essentially, I'm looking for the ideal data structure the has quick lookups for indexing keys, and quick iteration for the time updates/size overflow evictions. 本质上,我正在寻找理想的数据结构,该结构具有用于索引键的快速查找以及用于时间更新/大小溢出逐出的快速迭代。

Making a Dictionary was my first thought, and that certainly has fast indexing, but given I'm going to be removing elements and adding new ones fairly regularly, I'm concerned about the performance. 制作字典是我的第一个想法,并且肯定具有快速的索引编制能力,但是鉴于我将定期删除元素并添加新元素,因此我担心性能。 List> could work, but then lookup is going to take time. List>可以工作,但是查找将需要一些时间。

For reference, I was likely going to be limiting the cahce to about 30-40 images at a time, and range anywhere from 2 kb to 500 kb and eviction time will typically be about ~6 minutes. 作为参考,我可能一次将cahce限制为大约30-40张图像,范围从2 kb到500 kb,逐出时间通常约为6分钟。 I'd like to be able to check for evictions at least every 1-2 seconds 我希望能够至少每1-2秒检查一次驱逐

I was wondering if anyone could provide some insight into the best type of data structure to use for this. 我想知道是否有人可以提供一些有关最佳数据结构类型的见解。

Thanks 谢谢

For your stated use case (40 items in cache, eviction check every 1 second) a dictionary should be a completely fine data structure. 对于您陈述的用例(高速缓存中有40个项目,每1秒钟进行逐出检查),字典应该是一个完全好的数据结构。

If you are developing against .NET 4 you could also try the built-in MemoryCache class: http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx 如果您是针对.NET 4开发的,则还可以尝试使用内置的MemoryCache类: http : //msdn.microsoft.com/zh-cn/library/system.runtime.caching.memorycache.aspx

Either way, you should do some performance testing to make sure your application runs smoothly. 无论哪种方式,您都应该进行一些性能测试,以确保您的应用程序可以平稳运行。

A class in a library I wrote might give you some inspiration - it's similar but doesn't have the time-based cache eviction that you describe: 我编写的库中的一个类可能会给您一些启发-相似,但是没有您描述的基于时间的缓存驱逐:

https://github.com/xpaulbettsx/ReactiveXaml/blob/master/ReactiveXaml/MemoizingMRUCache.cs#L31 https://github.com/xpaulbettsx/ReactiveXaml/blob/master/ReactiveXaml/MemoizingMRUCache.cs#L31

The core thing to remember though, is that keeping 2 separate data structures isn't really the worst thing since your ImageEntry is a class (hint: don't make it a struct) and the raw image data will be orders of magnitude bigger than the extra overhead of maintaining both a dictionary and a list for example. 不过要记住的核心是,保留2个单独的数据结构并不是最糟糕的事情,因为ImageEntry是一个类(提示:不要使其成为结构),并且原始图像数据将比例如,同时维护字典和列表的额外开销。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM