为什么excel VBA代码在某些机器上运行速度慢2000倍?

u7up0aaq  于 2022-11-26  发布在  其他
关注(0)|答案(2)|浏览(721)

我创建了一个Excel VBA宏,它可以进行大量数据密集型处理。我经常使用Collections。在某些PC上,它运行得非常快,而在其他PC上,它运行得非常慢。我在下面的示例代码中隔离了问题。请注意,示例代码不是功能程序,它只是隔离了我在较大程序中遇到的技术问题。
我已经在4台不同的机器上测试了这个宏。请看下面的输出与CPU信息,都使用“Microsoft® Excel® Microsoft 365 MSO(版本2210 Build 16.0.15726.20188)32位”:
英特尔(R)酷睿(TM)i9- 10900 K CPU,主频3.70 GHz,内存16.0 GB:执行循环花了0.09秒。清除内存花了0.04秒。
第11代英特尔®酷睿™ i7- 1185 G7,主频3.00 GHz,内存16.0 GB:运行循环花了0.10秒。清除内存花了0.05秒。
英特尔(R)酷睿(TM)i7- 7700 K CPU,主频4.20 GHz,内存32.0 GB:执行循环花了162.58秒。清除内存花了5.48秒。
英特尔(R)酷睿(TM)i7- 8665 U CPU,主频1.90 GHz,内存16.0 GB:执行循环花了201.03秒。清除内存花了6.37秒。
VBA程序的代码:

Option Explicit
    
Sub largeCollection()

    Dim time1 As Single
    Dim time2 As Single
    time1 = Timer

    Dim myCollection As New Collection

    
    Dim I As Long
    Dim aClass1 As Class1
    
    For I = 2 To 50000
        Set aClass1 = New Class1

        aClass1.d1 = I
        aClass1.d2 = I
        aClass1.d3 = I
        aClass1.d4 = I
        aClass1.d5 = I
        aClass1.d6 = I
        aClass1.d7 = I
        aClass1.d8 = I
        aClass1.d9 = I
        aClass1.d10 = I

        aClass1.i1 = I
        aClass1.i2 = I
        aClass1.i3 = I
        aClass1.i4 = I
        aClass1.i5 = I
        aClass1.i6 = I
        aClass1.i7 = I
        aClass1.i8 = I
        aClass1.i9 = I
        aClass1.i10 = I
        
        myCollection.Add aClass1
    Next I
    
    time2 = Timer
    
    Set myCollection = Nothing
    
    'Notify user in seconds
    Debug.Print "Run loop took " & Format((time2 - time1), "0.00") & " seconds. Clearing memory took " & Format((Timer - time2), "0.00") & " seconds."
    
End Sub

自定义类“Class 1”的代码:

Option Explicit

Public s1 As String
Public s2 As String
Public s3 As String
Public s4 As String
Public s5 As String
Public s6 As String
Public s7 As String
Public s8 As String
Public s9 As String
Public s10 As String
Public s11 As String
Public s12 As String
Public s13 As String
Public s14 As String
Public s15 As String
Public s16 As String
Public s17 As String
Public s18 As String
Public s19 As String
Public s20 As String

Public v1 As Variant
Public v2 As Variant
Public v3 As Variant
Public v4 As Variant
Public v5 As Variant
Public v6 As Variant
Public v7 As Variant
Public v8 As Variant
Public v9 As Variant
Public v10 As Variant

Public i1 As Long
Public i2 As Long
Public i3 As Long
Public i4 As Long
Public i5 As Long
Public i6 As Long
Public i7 As Long
Public i8 As Long
Public i9 As Long
Public i10 As Long

Public d1 As Double
Public d2 As Double
Public d3 As Double
Public d4 As Double
Public d5 As Double
Public d6 As Double
Public d7 As Double
Public d8 As Double
Public d9 As Double
Public d10 As Double

我已经没有选择了,如果有人能提供解决方案就太好了。

goucqfw6

goucqfw61#

我们终于自己找到了答案,虽然不是很让人欣慰......性能的差异似乎完全取决于信任中心的宏设置。
如果我选择该选项:

  • “禁用宏并发出通知”,我必须显式“启用内容”才能在打开工作簿时启用宏。使用此选项,宏的运行速度会慢2000倍
  • “启用VBA宏(不推荐;可能运行潜在危险的代码)”代码运行速度快2000倍。

我希望这两个选项具有相同的性能,因为在启用内容后,我启用了VBA宏,就像我选择了另一个选项一样。
这意味着我拥有高性能宏的唯一方法是将该选项设置为“启用VBA宏(不推荐;潜在危险的代码可以运行)",这将导致所有工作簿的所有宏在默认情况下运行,即使我会打开来自第三方的随机excel,这是一个巨大的安全风险。

e3bfsja2

e3bfsja22#

在Class1中有很多变量,其中很多是变量,这需要更多的内存空间。尝试在Class1中创建新的集合来存储不同的变量。例如,变量v1,v2,... Vn可以是Class1中的新集合,其中包含“ClassV”中的对象。另外,您正在从i=2循环到i=50000。在下一个i之前,您可以设置setClass1 = Nothing来释放内存。

相关问题