2016-08-23 10 views
2

私は現在、大規模なデータセットをチャートにプロットできる管理可能なデータポイントにフィルタリングするプロジェクトを行っています。Excel VBAとJavascriptの大きなデータセットの反復処理のパフォーマンス

データの範囲を反復処理し、指定されたステップサイズ(この場合は開始値= 0およびステップサイズ= 0.1)で最初の値を選択する、Javascriptで次のコードを書きました。これはうまく動作し、非常に迅速に実行されます。私はそれを数値化していないが、間違いなく<> 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; 
    } 
} 

Codepen of Javascript with Mini Sample Dataset

しかし、我々のすべてのデータは、Excelワークブックのように来ているので、次のようにIは、隣接する列にデータポイントを出力する、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 

2つの方法の間にこのような大きな違いがあるのはなぜですか?私のVBコードについて何か驚くほど非効率的なものはありますか?私はこの質問があまりにも曖昧でないことを願っています

多くのおかげで、アダム

答えて

1

私はcyobashuからインスピレーションを取ったが、Redim Preserveを繰り返し呼び出しとTrasnpose方法を回避することにより、いくつかのパフォーマンスをeeked。

サイボーシャのコードを1m行に対して実行すると、約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 
4

は、そのほとんど同じ速JSの一つとして、あなたのコードの配列の実装を参照してください。

10,000データポイントでは、少なくとも私のマシンでは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 
    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 
関連する問題