优化慢速VBA代码

时间:2013-06-28 13:46:26

标签: arrays performance vba montecarlo

代码(采用随机生成的2d数组(R,C)),每个月(21天)将结果分成两个数组(平均值为1,曝光量为1)

 Public R As Double
 Public C As Integer
 Public Strike,Spot,Ton  As Double
 Public Ton As Double
 Public AVG(), EXP(), w() As Variant
 ''''''''''''''
 Sub Start()
 sss = SetParmeters()
 MonteCarlo (Copy2Array())
 i = calcW()
 cpSheet (True)
 End Sub 
 '''''''''''''''
  Function SetParmeters() As Boolean
 Dim w As Worksheet
 Set w = Worksheets("Copper daily moves")
R = w.Range("cc")
C = w.Range("row")
Strike = w.Range("strike")
Spot = w.Range("spot")
Ton = w.Range("ton")
End Function                       
'''''''''''''''''''
Function Copy2Array() As Variant
  Dim w As Worksheet
  Set w = Worksheets("Copper daily moves")
  Copy2Array = w.Range("price")
 End Function
''''''''''''''''''''
 Function MonteCarlo(p As Variant)
 ReDim w(R, C)
 For i = 0 To R
 s = Spot
 For j = 0 To C
 w(i, j) = s * (1 + p(Application.WorksheetFunction.RandBetween(1, 1275), 1))
 s = w(i, j)
 Next j
 Next i
 End Function
''''''''''''''''
 Function calcW() As Boolean
 ReDim AVG(R, (C / 21) - 1)
 ReDim EXP(R, (C / 21) - 1)
 Count21 = 0
 countW = 0
 For i = 0 To R
 Sum = 0
 countW = 0
 Count21 = 21
 For j = 0 To C
 Sum = Sum + w(i, j)
 If Count21 = j Then
 AVG(i, countW) = Sum / 21
 If Strike > AVG(i, countW) Then
 EXP(i, countW) = (Strike - AVG(i, countW)) * ((C / 21) - countW) * Ton
 Else
 EXP(i, countW) = 0
 End If
 countW = countW + 1
 Count21 = Count21 + 21
 Sum = 0
 End If
 Next j
 Next i
 End Function
''''''''''''''
Sub cpSheet(flag)
Addr = "$A$1"
Addr = Addr & ":" & Range(Addr).Cells(UBound(AVG), _
UBound(AVG, 2) + 1).Address
Worksheets("AVG").Range(Addr).Value = AVG
Worksheets("EXP").Range(Addr).Value = EXP
End Sub

主要问题是处理数据需要很长时间(特别是在进行100k模拟(行)及以上时),因此使用Excel工作表而不是VBA可能会更快!!

我测试了它(R = 100k,c = 252)并且大约需要8分钟,是否有任何方法可以优化代码以使其运行得更快?

1 个答案:

答案 0 :(得分:1)

尽量不要使用Variant类型,并使用

Application.ScreenUpdating = False

在代码的早期和

Application.ScreenUpdating = True

...代码末尾。

另一个提示是用“\”除法替换“/”除法(返回单个值)(返回一个整数值)。特别是在一个循环中,这可以提高他的表现。