redim在VBA中使用堆内存还是栈内存?

问题描述 投票:0回答:1

我知道要求一种远离 C 和 C++ 等低级语言的语言是很奇怪的,但它引起了我的注意,例如如果我这样做:

Dim tempArray(0 To 2) As Integer

显然,出于很多原因,我将使用堆栈内存,但让我们坚持这样的想法:这是一个预定义大小的数组,因此它是静态的,而不是动态的。但假设我这样做:

Dim tempArray() As Integer
Dim arraySize As int
Dim inputData As String

inputData = InputBox("Please give me the size of your array")

arraySize = Val(inputData)

Redim tempArray(0 To arraySize)

假设用户确实给了我们一个有效的数字,你们都可以同意这种动态分配,因为它是在运行时完成的,所以,当我在 VBA 中编程时,我必须记住使用 redim 速度较慢,因为不仅我正在进行重新分配,但也是因为我要使用堆,对吗?我再次知道,如果我如此关心知道正在使用哪种内存,我应该使用其他类型的语言,但只是我真的想了解有关 Redim 过程的所有内容,但我找不到对我的问题有很多见解,所以任何答案都会非常有帮助。

excel vba heap-memory dynamic-memory-allocation dynamic-arrays
1个回答
0
投票

当您在 VBA(Visual Basic for Applications)中使用

ReDim
时,您确实是在运行时执行动态内存分配,这涉及到重新分配内存。
以下是该过程及其含义的详细说明:

静态与动态分配

1-静态分配:

Dim tempArray(0 To 2) As Integer

tempArray
的内存在编译时分配在堆栈上。
数组的大小是固定的,并在编译时确定。
堆栈分配通常更快、更高效,因为它涉及简单的指针调整。

2-动态分配:

Dim tempArray() As Integer
Dim arraySize As Integer
Dim inputData As String

inputData = InputBox("Please give me the size of your array")
arraySize = Val(inputData)
ReDim tempArray(0 To arraySize)  

tempArray
的内存在运行时在堆上分配。
数组的大小是在运行时根据用户输入确定的。
与堆栈分配相比,堆分配速度较慢,因为它涉及更复杂的内存管理操作,例如查找合适的内存块以及可能移动现有数据。

ReDim
过程

当您在 VBA 中使用

ReDim
时:

1-内存分配:

VBA 在堆上分配新的内存块以容纳数组的新大小。
旧内存块被释放(释放),这涉及更新内部内存管理结构以将其标记为可用。

2- 数据移动(如果使用

ReDim
保留):
如果使用
ReDim Preserve
,VBA需要将数组的现有元素复制到新分配的内存块中。
这会增加开销,因为它涉及迭代现有元素并将它们一一复制到新的内存位置。

性能注意事项:

速度

由于堆内存管理和潜在的数据移动的开销,动态分配 (

ReDim
) 通常比静态分配慢。
对于小型阵列来说,速度差异可能可以忽略不计,但对于较大阵列或性能关键型应用程序来说,速度差异可能会变得很大。

内存使用情况

堆分配允许更灵活的内存使用,从而可以根据运行时要求动态调整数组大小。
但是,频繁使用

ReDim
调整大小可能会导致内存碎片并增加内存使用量。

最佳实践:

尽量减少

ReDim
的使用:
尝试尽量减少
ReDim
操作的数量,尤其是在性能关键的循环内。
如果您需要多次调整数组大小,请考虑以更大的增量调整大小以减少分配数量。

避免不必要的

ReDim Preserve

仅当您需要保留现有数据时才使用
ReDim Preserve

如果数据不需要保留,不带 Preserve 的简单
ReDim
会更高效。

结论:

总而言之,在 VBA 中使用

ReDim
涉及到堆上的动态内存分配,由于内存管理和潜在数据移动的开销,与堆栈上的静态分配相比要慢。
虽然 VBA 抽象了大部分复杂性,但了解这些底层流程可以帮助您编写更高效的代码,尤其是在处理大型数据集或性能关键场景时。

© www.soinside.com 2019 - 2024. All rights reserved.