如何在C#中使用一个非常大的字典?

7
我想在C#应用程序中使用查找映射表或字典,但预计需要存储1-2 GB的数据。请问是否仍可使用字典类,或者需要使用其他类?
编辑:我们有一个现有的应用程序,它使用oracle数据库查询或查找对象详细信息。然而,由于重复查询相同的对象,速度太慢了。我认为在这种情况下使用查找映射表可能是理想的选择,以改善响应时间。但我担心大小会成为问题。

你尝试过启动一个使用那么多内存的字典实例吗?此应用程序部署在32位还是64位系统上? - RQDQ
1
为什么要使用字典或内存数据结构?为什么不使用数据库? - Forgotten Semicolon
2
SqlLite有一个很酷的内存数据库,可能对你的情况很有趣。 - gt124
如果你在2GB的计算机上进行计算并且你控制服务器本身,那就直接开始吧。没有任何服务器会比使用“16可用中的3GB”而不是“16可用中的14GB”更好。内存的工作方式并非如此,对于读写访问,没有什么比RAM更快。如果内存负载是一个问题,其他评论在这里更值得关注! - Independent
我听说过 C++ 的外部内存 STL 容器,但不知道 C# 是否有类似的替代方案? - paseena
你应该优化你的数据库。 - SLaks
6个回答

7

简短回答

是的。如果你的机器有足够的内存来存储这个结构(以及程序和系统的其他开销,包括操作系统)。

长回答

你确定要这么做吗?不知道你的应用程序更多的信息,很难知道该提出什么建议。

  • 数据从哪里来?文件?文件?数据库?服务?
  • 这是一个缓存机制吗?如果是,当一个项目已经有一段时间没有被访问时,您可以将其从缓存中删除吗?这样,您就不必一直将所有信息保存在内存中。
  • 正如其他人所建议的那样,如果您只是想存储大量数据,您可以使用数据库吗?这样,您就不必一次性将所有信息保存在内存中。通过索引,大多数数据库都能够执行快速检索。您可以将此方法与缓存相结合。
  • 将存储在内存中的数据是只读的,还是需要在某些更改时将其持久化到某些存储中?
  • 可扩展性 - 您是否期望存储在此字典中的数据量会随着时间的推移而增加?如果是这样,您将遇到一个非常昂贵的点,即购买可以处理此数据量的机器。如果是这种情况,您可能需要查看分布式缓存系统(例如AppFrabric),以便您可以水平扩展(更多机器)而不是垂直扩展(一个非常大的昂贵的故障点)。

更新

根据发布者的编辑,听起来在这里使用缓存会有很大的帮助。有许多方法可以做到这一点:

  • 简单的字典缓存 - 只需在请求时缓存内容。
  • Memcache
  • 缓存应用程序块我不是这种实现的铁杆支持者,但其他人已经取得了成功。

1
只要你使用的是64GB的计算机,你应该能够使用这么大的字典。但是如果你有这么多数据,使用数据库可能更合适(cassandra其实就像一个巨大的字典,而且总会有MySQL等其他选择)。

1
只是一点小提示...应用程序需要编译为64位(或在64位机器上的任何CPU)才能使进程占用超过2GB的内存(我想它是2GB)。 - Giovanni Galbo

1

当你说1-2GB的数据时,我认为你指的是这些项目是累积包含1-2GB的复杂对象。

除非它们是结构体(而且不应该是),否则字典不在乎项目有多大。
只要你少于大约224个项目(我随意选了这个数字),你可以将尽可能多的东西存储在内存中。

然而,正如其他人建议的那样,你应该使用数据库。
你可能想使用像SQL CE这样的内存数据库。


0

你可以这样做,但对于如此大的字典,最好使用数据库。


0

使用数据库。 确保您拥有良好的数据库模型,放置正确的索引,然后开始吧。


-2

你可以使用 子字典

Dictionary<KeyA, Dictionary<KeyB ....

KeyAKeyB 的一部分。

例如,如果您有一个字符串字典,可以使用第一个字母作为 KeyA


这如何回答问题?这看起来像一个晦涩的缓存分区方案,与回答用户是否应该缓存数据库结果无关。 - RQDQ
它解决了一个问题,是分区方案(字典的问题 - 内存分配,当内存用尽时,它会分配两倍的内存,并且使用分区方案可以使过程不那么痛苦),似乎这是你想要在RAM中拥有真正大的字典的唯一方法(不在数据库中),当然如果你有很多RAM,或者你将会遇到内存不足的情况。另外,你可以尝试将应用程序切换到64位 - 也许这应该是你应该尝试的第一步... - Evgeny Bestfator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接