迭代大型数据集的 Excel VBA 与 Javascript 性能对比

awe*_*orn 4 javascript excel vba for-loop

我目前正在做一个项目,涉及将大型数据集过滤为可以在图表上绘制的可管理数量的数据点。

我用 Javascript 编写了以下代码,该代码迭代一系列数据并以给定步长选取第一个值,在本例中起始值 = 0,步长 = 0.1。这非常有效并且执行速度非常快;我还没有量化它,但对于 >10000 个数据点来说绝对是 <1 秒。

var data = [ ... ];

var filteredData = [];
var index = 0;
var step = 0.1;

for (var i=0; i < data.length; i++) {
  if(data[i] >= index) {
    filteredData.push(data[i]);
    index+=step;
  }
}
Run Code Online (Sandbox Code Playgroud)

带有迷你样本数据集的 Javascript Codepen

但是,我们所有的数据都以 Excel 工作簿的形式传入,因此我使用 VBA 将代码重写为 Excel 宏,如下所示,将数据点输出到相邻列。与 JS 等价物相比,处理相同数量的数据点需要很长的时间,处理 10000 个数据点大约需要 20 秒。

Dim dataRange As Range
Set dataRange = Range(Range("A8"), Range("A8").End(xlDown))
Dim index As Double
Dim stepsize As Double
Dim outputRow As Integer
index = 0
step = 0.1
outputRow = 8

For Each cell In dataRange
    If cell.Value >= index Then
        ActiveSheet.Cells(outputRow, 2).Value = cell.Value
        index = index + stepsize
        outputRow = outputRow + 1
    End If
Next cell
Run Code Online (Sandbox Code Playgroud)

为什么两种方法之间存在如此巨大的差异?我的 VB 代码有什么明显低效的地方吗?我希望这个问题不要太模糊!

非常感谢,亚当

cyb*_*shu 5

查看代码的 Array 实现,它几乎与 JS 一样快。

10,000 个数据点只需要不到一秒的时间(至少在我的机器上)。

Sub test()

    Dim dataRange As Range
    Set dataRange = Range(Range("A8"), Range("A8").End(xlDown))
    Dim index As Double
    Dim stepsize As Double
    Dim outputRow As Long

    index = 0
    step = 0.1
    outputRow = 8


    '/ Array implementation in VBA
    '/ Its almost at the same speed.
    '----------------------------------------------------
    Dim lctr        As Long
    Dim oRow        As Long
    Dim arrOut()
    Dim arr
    arr = dataRange

    For lctr = LBound(arr) To UBound(arr)
        If arr(lctr, 1) >= index Then
            index = index + stepsize
            oRow = oRow + 1
            ReDim Preserve arrOut(1 To 1, 1 To oRow)
            arrOut(1, oRow) = arr(lctr, 1)
        End If
    Next

    arrOut = Application.Transpose(arrOut)

    ActiveSheet.Cells(8, 2).Resize(UBound(arrOut)) = arrOut

    '------------------------------------------------------------



'    For Each cell In dataRange
'        If cell.Value >= index Then
'            ActiveSheet.Cells(outputRow, 2).Value = cell.Value
'            index = index + stepsize
'            outputRow = outputRow + 1
'        End If
'Next cell

End Sub
Run Code Online (Sandbox Code Playgroud)