Excel VBA vs Javascript性能,用于迭代大数据集

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

我用Javascript编写了下面的代码,遍历一系列的数据,并以给定的步长挑出第一个值,在这个例子中,start = 0,step = 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; } } 

使用迷你样本数据集的Javascript的Codepen

但是,我们所有的数据都是以Excel工作簿forms出现的,所以我使用VBA将这些代码重写为Excelmacros,如下所示,将数据点输出到相邻的列。 处理相同数量的数据点与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 

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

非常感谢,亚当

我从cyobashu获得灵感,但通过避免重复调用Redim PreserveTrasnpose方法,取消了一些性能。

当我对1m行运行cybojs的代码时,大约需要16秒。 当我运行下面的代码对1m行,大约需要1秒。

我也已经解决了我认为是一个错字step = 0.1应该是stepsize = 0.1

 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 stepsize = 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 ReDim arrOut(LBound(arr) To UBound(arr), LBound(arr, 2) To UBound(arr, 2)) As Variant For lctr = LBound(arr) To UBound(arr) If arr(lctr, 1) >= index Then index = index + stepsize oRow = oRow + 1 arrOut(oRow, 1) = arr(lctr, 1) End If Next ActiveSheet.Cells(8, 2).Resize(oRow) = arrOut End Sub 

查看你的代码的数组实现,它的速度几乎和JS一样快。

这将需要(至less在我的机器上)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