考虑以下代码:
function Foo(ds as OtherDLL.BaseObj)
dim lngRowIndex as long
dim lngColIndex as long
for lngRowIndex = 1 to ubound(ds.Data, 2)
for lngColIndex = 1 to ds.Columns.Count
Debug.Print ds.Data(lngRowIndex, lngColIndex)
next
next
end function
好的,一点上下文。参数ds
的类型为OtherDLL.BaseObj,它在引用的ActiveX DLL中定义。 ds.Data
是一个变量二维数组(一个维度包含数据,另一个维度包含列索引。ds.Columns
是'ds.Data`中的列集合。
假设至少有400行数据和25列,此代码在我的机器上运行大约需要15秒。有点令人难以置信。
但是,如果我将变量数组复制到局部变量,那么:
function Foo(ds as OtherDLL.BaseObj)
dim lngRowIndex as long
dim lngColIndex as long
dim v as variant
v = ds.Data
for lngRowIndex = 1 to ubound(v, 2)
for lngColIndex = 1 to ds.Columns.Count
Debug.Print v(lngRowIndex, lngColIndex)
next
next
end function
整个过程几乎没有任何明显的时间(基本上接近0)。
为什么呢?
答案 0 :(得分:2)
有可能ds.Data每次访问时都会创建/复制整个数组(例如,通过从数据库或其他东西中获取),这需要花费大量时间。
通过在循环内访问它,您将进行数百次复制操作。在第二种情况下,将其复制到循环外的局部变量中,然后快速重复使用该数据数百次,而无需再次实际复制。
这是一种常见且非常重要的优化技术:将任何不必要的工作移出循环,以便尽可能少地执行。只是在你的例子中,当你访问数据时它正在做很多额外的工作并不“显而易见”。