我写了一个大型的VBA程序,概括地说,它计算建筑物的能源需求。可能会在这里发布大量代码,但首先它会读取每个建筑物的配置文件,然后从磁盘加载一些热负荷曲线,然后动态计算35040个四分之一小时的热量产生者产生的热量。
在具有Windows Defender的Windows 7上,无论使用什么Excel版本(经过测试的2007、2010、2013、365),它都可以流畅,良好地运行。
现在,如果我在装有Windows 10和Windows Defender(Excel 365)的计算机上运行相同的代码,它的速度将降低令人难以置信的速度(感觉是1000左右)。奇怪的是,一切都变慢了,这不是某个过程或事件。从磁盘加载文件和配置文件需要花费很多时间,但是计算循环中的能量需求(其中没有任何东西从驱动器传输到驱动器)也要慢得多。 GUI根本不刷新,整个应用程序似乎冻结了。
同时MsMpEng.exe处于满负载,表明Windows Defender存在问题。令人惊讶的是,关闭Windows Defender后,一切运行正常。
现在,因为有太多的类/模块/等。很难说,这可能是问题所在,我无法上传代码。但是至少我有一个怀疑。每个类都有一个父属性,如here所示实现。 parent属性在代码中经常被调用,因此,如果CopyMemory-API / Function存在问题,则极慢的速度是有意义的。
更新1 : 我删除了CopyMemory-Function并将所有的Parents替换为循环引用。这不是长期解决方案,但解决了部分问题。当我等待足够长的时间时,计算将在某个时间点开始,并且会像预期的那样快。因此,问题通常可能与API函数有关,因为我在GUI上使用了很多,即
Public Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
Public Declare PtrSafe Function GetDeviceCaps Lib "Gdi32" (ByVal hDC As LongPtr, ByVal _
nIndex As Long) As Long
Public Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal _
hDC As LongPtr) As Long
Public Declare PtrSafe Function GetSystemMetrics32 Lib "user32" _
Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long
Public Declare PtrSafe Function SetWindowPos Lib "user32" _
(ByVal hWnd As LongPtr, ByVal hWndInsertAfter As LongPtr, _
ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long
Public Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hWnd As LongPtr) As Long
Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
Public Declare PtrSafe Sub ReleaseCapture Lib "user32" ()
Public Declare PtrSafe Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" _
(ByVal hInst As LongPtr, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As LongPtr
Public Declare PtrSafe Function GetActiveWindow32 Lib "user32" Alias "GetActiveWindow" () As Integer
#If Win64 Then
Public Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" _
(ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Public Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" _
(ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
更新2 (使主题以某种方式解决)
程序的载入部分之所以花了很长时间,是因为我使用了JSON-Converter。事实证明,这里有一个similar problem。自从我更新了该模块并删除了所有其他API-Call以来,一切都运行顺利。所以它肯定是由API调用引起的,尽管我不知道为什么没有那么多其他人抱怨巨大的性能问题。现在,我无法以我不想使用的方式来调整GUI,而且我真的不知道如何正确地实现父属性。