【问题标题】:C# Programming: Maintaining a List that Associates an ID with Information QuicklyC# 编程:维护一个快速关联 ID 和信息的列表
【发布时间】:2011-10-26 10:56:49
【问题描述】:

在我一直在开发的一款游戏中,我创建了一个系统,游戏通过该系统轮询特定的“ItemDatabase”文件,以便根据给定的标识号检索有关自身的信息。标识号代表数据库中存储有关特定项目的信息的点。数据库中每个项目的表示由 162 个字节组成。系统代码类似如下:

// Retrieves the information about an 'Item' object given the ID.  The 
// 'BinaryReader' object contains a file stream to the 'ItemDatabase' file.
public Item(ushort ID, BinaryReader itemReader)
{
    // Since each 'Item' object is represented by 162 bytes of information in the 
    // database, skip 162 bytes per ID skipped.
    itemReader.BaseStream.Seek(162 * ID, SeekOrigin.Begin);

    // Retrieve the name of this 'Item' from the database.
    this.itemName = itemReader.ReadChars(20).ToString();
}

这个系统通常不会有什么特别的问题,因为它会查询所需的数据并将其初始化为正确的变量。然而,这个过程必须在游戏期间发生,并且根据我对“Seek”方法的效率所做的研究,这种技术的速度几乎不足以融入游戏中。所以,我的问题是:有什么好的方法可以维护一个将识别号与可以快速访问的信息相关联的列表?

【问题讨论】:

  • 有什么原因不能将整个文件加载到内存中的数组中吗?如果确实需要,操作系统将负责将内存分页到磁盘。一旦它进入一个数组,就可以快速轻松地处理每个项目。
  • 随着游戏开发的继续,可能会有非常大的项目列表。比如说,如果列表达到 3000 个左右的独特项目,会不会对记忆造成负担?我只是想确保我不会在 RAM 中加载太多,同时仍然尽可能快地加载项目。
  • 在现代 PC 上,每个 162 字节的 3,000 个项目都不算什么。那只有 486,000 字节。在过去,您可能会遇到麻烦,当时您的内存空间必须大大小于 640K,但您使用的是 C# 和托管代码(并且运行时占用的空间远远超过 640K)。在达到数百 MB 之前,您真的不需要担心。
  • 那么,如果我完全填满了项目列表(每个项目 162 字节,最多 65536 个项目,所以大约 10 MB),我仍然是清楚的吗?非常感谢您的帮助!

标签: c# database database-design


【解决方案1】:

你最好的选择是数据库。 SQLite 非常便携,不需要在系统上安装。

如果您已将所有数据加载到内存中,则可以使用Dictionary<int, Item>。这使得向列表中添加和删除项目变得非常容易。

由于您的 ID 似乎都是从 0 及以上开始,因此仅使用一个数组会非常快。只需将项目的索引设置为id即可。

【讨论】:

  • 如果 ID 是连续的(从示例代码中可以看出),数组会快得多。
【解决方案2】:

假设“数据库”中的信息不是不断变化的,你不能在游戏或关卡的加载过程中一次性读出各种项目吗?您可以以多种方式存储数据,例如字典。 .Net 字典实际上是通常所说的哈希表,将键(在本例中为您的 ID 字段)映射到对象(我猜是“项目”类型)。查找时间非常好(肯定是每秒数百万),我怀疑你会遇到问题。

或者,如果您的 ID 是 ushort,您可以将对象存储在包含所有可能的 ushort 值的数组中。 65535 长度的数组在今天看来并不大。数组查找尽可能快。

【讨论】:

  • 项目的绝对最大数量为 65536 个项目(我怀疑我永远不会达到,但我希望有比一个字节提供的更多空间)。那么,如果我加载一个包含 65536 个项的数组,对内存资源的负担不会太大吧?
  • 嗯,你说每一项是162字节,所以162 * 65536 = 10616832字节。这只是超过 10 兆字节,在今天看来这并不多,除非您正在为手机或其他此类设备编写代码。
【解决方案3】:

您可以使用Dictionary,或者如果在多线程应用程序中使用它,则使用ConcurrentDictionary

MemoryMappedFile 的实现速度极快但需要付出更多努力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    相关资源
    最近更新 更多