我有大量同一类obj
的对象,目前定义为obj[]
。
在大多数情况下,这些obj
只是default(obj)
,最好是实施IEnumerable<obj>
而不是这些obj[]
列表吗?
这应该为我释放记忆,对吧? 目前,这些对象(运行内存分析器)的数量为200k(不断增长)。
将列表更改为IEnumerables会对我有帮助吗?
答案 0 :(得分:1)
IEnumerable
只是一个界面;它没有规定任何存储数据的方式。 List
只包含一个在向其中添加更多项目时会增长的数组,但您可以调用TrimExcess()
方法来缩小数组。
答案 1 :(得分:1)
List<T>
的实际实现基于数组,因此两者之间的内存使用差异可以忽略不计。
就IEnumerable<T>
而言:不,它不会为你节省任何记忆。 null
或default
元素在IEnumerable<T>
内完全可以接受,并且框架不会对重复项进行任何操作。它不能,因为与IEnumerable<T>
结构相关联的内存占用完全依赖于实现它的类,如果你只是将一个数组放入一个可枚举的变量或字段中,那么你就不会改变任何实质内容。可枚举也是不可变的,因此建议的切换可能是对阵列实现的重大改变。
如果您不关心订购,可以使用HashSet<T>
。这实际上会过滤重复项,因此如果您的许多或大部分元素都是default(T)
,那么您只需要其中一个元素的内存。显然,这将消除所有重复项,而不仅仅是默认重复项,因此只有在没有其他重复项时,此选项才有用。
如果你需要可变语义 - 我怀疑如果你正在使用数组 - 那么你可以(并且应该)切换到可变接口,例如{ {1}},并编写您自己的实现 - 可能基于IList<T>
- 当您尝试添加时忽略List<T>
。这样,您可以保留非default(T)
元素的顺序,而无需分配任何内存来保存default
元素。
如果您确实需要保留原始元素的所有,那么没有简单的数据结构可以帮助您。我可以建议一个数据库吗?我知道现在内存很丰富,但是当你存储数十万个项目时,你至少应该考虑为这种规模设计的数据结构或系统。
答案 2 :(得分:0)
正如Mark所说,IEnumerable只是一个界面。 Object []和List(以及.NET框架中的大多数其他通用集合)实际上实现了IEnumerable接口。
更合适的问题是Object []或List或LinkedList等是否更好。
对象数组(即Object [])将具有最小的内存占用量,因为List可能是数组内存大小的两倍(取决于列表中的元素数量)。当您向List添加项目并且内部数组已满时,它会使数组的大小加倍,以尝试从算法的角度平均更快地添加新元素。