【问题标题】:List vs. Dictionary (Maximum Size, Number of Elements)列表与字典(最大大小,元素数量)
【发布时间】:2012-02-12 04:23:35
【问题描述】:

我正在尝试确定列表和字典的最大大小(在 RAM 中)。我也很好奇每个元素/条目可以容纳的最大数量,以及每个条目的内存占用。

我的理由很简单:我和大多数程序员一样,有些懒惰(这是一种美德)。当我编写一个程序时,我喜欢只写一次,并尽可能地适应未来。我目前正在编写一个使用列表的程序,但注意到迭代器需要一个整数。由于我的程序的功能仅受可用内存/编码样式的限制,因此我想编写它,以便可以使用带有 Int64 或 BigInts 的 List(作为迭代器)。我在这里看到了 IEnumerable 的可能性,但想知道我是否可以将 Int64 作为键填充到 Dictionary 对象中,而不是重写所有内容。如果可以的话,我想知道与重写它相比的成本是多少。

我希望如果我的程序证明有用,我只需在 5 年内重新编译即可利用内存的增加。

【问题讨论】:

    标签: c# .net list c#-4.0 dictionary


    【解决方案1】:

    它是否在该类的文档中指定?不,那么它是未指定的。

    就当前的实现而言,类本身的 RAM 中没有最大大小,如果您创建一个大小为 2MB 的值类型,将几千个推入列表中,并收到内存不足异常,这没什么使用List<T>

    在内部,List<T>s 的工作方式将阻止它拥有超过 20 亿个项目。很难用Dictionary<TKey, TValue> 快速回答,因为在其中放置东西的方式更复杂,但实际上,如果我正在考虑处理十亿个项目(例如,如果一个 32 位值,那么4GB),我希望将它们存储在数据库中并使用数据访问代码检索它们。

    至少,一旦您处理的是 4GB 大小的单个数据结构,滚动您自己的自定义集合类不再算作重新发明轮子。

    【讨论】:

    • 很公平。我很好奇,因为 List 迭代器似乎不喜欢 Int64s。
    • “不喜欢”是什么意思?
    • List parentnodes = new List(); for (Int64 i = 0; i
    • 它需要一个 int,并且似乎只接受一个 int,而不是一个 Int64 用于索引。
    • List<string> 也是如此。索引器与不喜欢类型无关。
    【解决方案2】:

    我正在使用并发词典对 50 万场围棋中的 3x3 模式进行排名。显然有很多可能的模式。在 C# 4.0 中,并发字典在大约 1.2 亿个对象处内存不足。当时它正在使用 8GB(在 32GB 机器上),但我认为它想要增长太多(表增长发生在并发字典的大块中)。我认为使用数据库会使我的速度至少减慢一百倍。而且这个过程已经花费了 10 个小时。

    我的解决方案是使用多阶段解决方案,实际上是进行多次传递,每个模式子集一次。就像奇数模式一次通过,偶数模式一次通过。当使用更多对象不再失败时,我可以减少通过次数。

    C# 4.5 通过对数组使用无符号 32 位指针增加了对 64 位更大数组的支持 (提到的限制从 20 亿到 40 亿)。也可以看看 http://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx。不确定哪些对象会从中受益,List 可能。

    【讨论】:

      【解决方案3】:

      我认为你有更大的问题需要解决,甚至不知道带有int64 密钥的Dictionary 是否会在 5 或 10 年内有用。

      内存中有 2e+10 个元素的 ListDictionary (int32) 似乎不是一个好主意,更不用说 9e+18 个元素 (int64)。无论如何,该框架永远不会允许您创建一个大小(甚至不接近)的怪物,并且可能永远不会。 (请记住,一个简单的int[int.MaxValue] 数组已经远远超出了框架对任何给定对象的内存分配限制)。

      问题仍然存在:您为什么希望您的应用程序在内存中保存这么多项目的列表?如果您必须管理大量信息,最好使用专门的数据存储后端(数据库)。

      【讨论】:

      • 处理超大树。这种大小的数据库实际上会比我想到的方法慢。尽管如此,我的意思是编写代码,以便以后不需要重新编写代码,因为内存大小仍在增长(最后我检查过)。
      • “请记住,一个简单的 int[int.MaxValue] 数组已经远远超出了框架对任何给定对象的内存分配限制)。”您实际上是指键在字典中的大小,而不是它将包含的对象,对吗?
      • @Marco:键和对象。它们必须存在于内存中的某个地方,而您不能分配那么多内存。字典包含对对象的引用而不是对象本身的事实在任何方面都没有帮助。
      • @InBetween 肯定有问题,至于 clr 内存分配限制:blogs.msdn.com/b/joshwil/archive/2005/08/10/450202.aspx。你不能肯定地说 int[int.MaxValue] 超出了内存分配的限制,我相信。
      • 在我多年的编程生涯中,我不得不构建许多应用程序,希望尽可能多地在内存中存储,通常是出于速度的原因。数据库访问(如果基于磁盘)要慢几个数量级。大型稀疏矩阵、运输问题、大型离散仿真模型等只是其中的几个示例。
      猜你喜欢
      • 2023-03-29
      • 2019-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      相关资源
      最近更新 更多