Vb.net 列表和数组大小差异
我的印象是List(Of T)是一个围绕基本数组的实用程序包装器,但今天在测试时,我发现List在内存中的大小是数组的两倍。这与我有关,因为我当前的实现使用列表,数据库大约是1.5gb,这对我来说有点太接近32位的限制,因为这不包括程序的其余部分。如果我能把它切成两半,那就太棒了 我使用列表来方便调整大小,但我想我可以围绕数组构建自己的包装器类,以更低的内存使用率实现同样的功能。所以我做的测试是:Vb.net 列表和数组大小差异,vb.net,Vb.net,我的印象是List(Of T)是一个围绕基本数组的实用程序包装器,但今天在测试时,我发现List在内存中的大小是数组的两倍。这与我有关,因为我当前的实现使用列表,数据库大约是1.5gb,这对我来说有点太接近32位的限制,因为这不包括程序的其余部分。如果我能把它切成两半,那就太棒了 我使用列表来方便调整大小,但我想我可以围绕数组构建自己的包装器类,以更低的内存使用率实现同样的功能。所以我做的测试是: Public Class funnylist Private arrlist As New
Public Class funnylist
Private arrlist As New List(Of Long())
Private rcount As Integer = 0
Private incsize As Integer = 1000
Private lastArr As Integer = -1
Private maxCount As Integer = 0
Private lastsub As Integer = -incsize
Public Sub add(n As Long)
If rcount = maxCount Then
arrlist.Add(New Long(incsize) {})
lastArr += 1
lastsub += incsize
maxCount += incsize
End If
arrlist(lastArr)(rcount - lastsub) = n
rcount += 1
End Sub
End Class
显然可以使用一些修饰,但作为概念证明,它是有效的,相同数量的项目的内存占用是列表(长)的一半。但问题是,我在列表和funnylist中填充了1000万个数字5并计时。列表的速度正好是它的两倍。所以我想知道在一份清单的掩护下到底发生了什么?为什么它更大,为什么更快?关于改进我的funnylist有什么建议吗?如果在包装器中专门使用长数组而不是(长的)列表,并在添加新数字时动态调整其大小,我很想看看性能会如何比较。试试这个。将Long传递给构造函数以初始化包装器的内部数组,然后使用Add方法添加更多的数字。您可以从MyArray属性检索当前数组
Public Class FunnyList
Private _myArray As Long()
Public Sub New(n As Long)
_myArray = New Long() {n}
End Sub
Public Sub Add(n As Long)
Dim iUBound As Integer = _myArray.GetUpperBound(0)
ReDim Preserve _myArray(iUBound + 1)
_myArray(iUBound + 1) = n
End Sub
Public ReadOnly Property MyArray() As Long()
Get
Return _myArray
End Get
End Property
End Class
您不希望列表的容量始终与元素的数量完全相同。列表的增长方式是战略性的。它不必每次添加元素时都执行分配。在您的情况下,由于存储的元素数量巨大,它可能会大大扩展。如果您知道您需要一定的大小,那么将列表初始化为该容量。当然,如果你需要一个静态大小,你也可以只使用一个数组…一个列表或数组可能需要两倍的内存是没有意义的。它是虚拟内存,只是处理器的一个数字。在访问真实内存之前,您不会开始使用它。这当然不会发生在顶端。当您编写的程序占用了所有可用的地址空间时,您就编写了错误的代码。任何从数据库中读取一组数据然后进行处理的程序都可以重写为一次处理一行,只需要千字节。你可以继续写糟糕的代码,允许它在64位模式下运行,很难耗尽地址空间。我不认为它是虚拟的,我是用64位编译的,当内存使用量达到15gb左右(我总共有16gb的物理内存)时,它崩溃了,出现了内存不足的异常。附言我实际上不想用64位编译它的原因是,这也使得整个程序运行速度大大降低(按我的衡量,大约是30%)我明白你所说的一次加载所有数据,但是会有大量的随机分布处理,每次访问磁盘都会适得其反。我试过了,相比之下,重拨速度非常慢(大约慢上千倍)。我怀疑它使用了和Array.Resize类似的机制,而我最初使用的机制也太慢了。此外,它还使内存的使用上下波动,我认为它只是创建一个新的数组,并在每次都完全复制旧的数组。