Skip to main content
added 167 characters in body
Source Link
Cristian Buse
  • 1.8k
  • 6
  • 29

Edit #1

The above has been extensively updated at the mentioned repository on GitHub at VBA-MemoryTools.

Edit #1

The above has been extensively updated at the mentioned repository on GitHub at VBA-MemoryTools.

added 34 characters in body; edited tags
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

I've been quite annoyed lately by the fact that the CopyMemoryCopyMemory API (RtlMoveMemoryRtlMoveMemory on Windows and MemMoveMemMove on Mac) is running much slower than it used to, on certain computers. For example on one of my machines (x64 Windows and x32 Office) the CopyMemoryCopyMemory API is running about 600 times slower than a month ago. I did do a Windows Update lately and maybe that is why. In this SO question is seems that Windows Defender is the cause of slowness. Regardless of why the API is much slower, it is unusable if the operations involving the API need to run many times (e.g. millions of times).

Even without the issue mentioned above, CopyMemoryCopyMemory API is slower than other alternatives. Since I did not want to use references to msvbvm60.dll which is not available on most of my machines, I decided to create something similar with the GetMemXGetMemX and PutMemXPutMemX methods available in the mentioned dll. So, I created a couple of properties (Get/Let) called MemByteMemByte, MemIntMemInt, MemLongMemLong and MemLongPtrMemLongPtr using the same ByRefByRef technique that I've used in the WeakReferenceWeakReference repository. In short, I am using 2 Variants that have the VT_BYREFVT_BYREF flag set inside the 2 Bytes holding the VarTypeVarType. These 2 Variants allow remote read/write of memory.

Since I couldn't use the same approach I've used for Byte, Integer and Long I've finally decided to go for the Currency approach because it was the cleanest and fastest. A Currency variable is stored using 8 Bytes in an integer format, scaled by 10,000 resulting in a fixed point number. So, it was quite easy to use currency instead of LongLongLongLong (see the MemLongPtrMemLongPtr Let property).

Another approach is to use a Double but looks absolutely horrendous (and is slower) and needs a second REMOTE_MEMORYREMOTE_MEMORY variable:

Another decision was to leave the DeRefMemDeRefMem method as a Sub. Consider the current code (excluding the VBA7 declarations):

I would be very grateful for suggestions that could improve the code.
Have I missed anything obvious? Are there any other useful methods that should be part of such a 'Memory' library (e.g. like I've added VarPtrArrayVarPtrArray and UnsignedAdditionUnsignedAddition)?

I've been quite annoyed lately by the fact that the CopyMemory API (RtlMoveMemory on Windows and MemMove on Mac) is running much slower than it used to, on certain computers. For example on one of my machines (x64 Windows and x32 Office) the CopyMemory API is running about 600 times slower than a month ago. I did do a Windows Update lately and maybe that is why. In this SO question is seems that Windows Defender is the cause of slowness. Regardless of why the API is much slower, it is unusable if the operations involving the API need to run many times (e.g. millions of times).

Even without the issue mentioned above, CopyMemory API is slower than other alternatives. Since I did not want to use references to msvbvm60.dll which is not available on most of my machines, I decided to create something similar with the GetMemX and PutMemX methods available in the mentioned dll. So, I created a couple of properties (Get/Let) called MemByte, MemInt, MemLong and MemLongPtr using the same ByRef technique that I've used in the WeakReference repository. In short, I am using 2 Variants that have the VT_BYREF flag set inside the 2 Bytes holding the VarType. These 2 Variants allow remote read/write of memory.

Since I couldn't use the same approach I've used for Byte, Integer and Long I've finally decided to go for the Currency approach because it was the cleanest and fastest. A Currency variable is stored using 8 Bytes in an integer format, scaled by 10,000 resulting in a fixed point number. So, it was quite easy to use currency instead of LongLong (see the MemLongPtr Let property).

Another approach is to use a Double but looks absolutely horrendous (and is slower) and needs a second REMOTE_MEMORY variable:

Another decision was to leave the DeRefMem method as a Sub. Consider the current code (excluding the VBA7 declarations):

I would be very grateful for suggestions that could improve the code.
Have I missed anything obvious? Are there any other useful methods that should be part of such a 'Memory' library (e.g. like I've added VarPtrArray and UnsignedAddition)?

I've been quite annoyed lately by the fact that the CopyMemory API (RtlMoveMemory on Windows and MemMove on Mac) is running much slower than it used to, on certain computers. For example on one of my machines (x64 Windows and x32 Office) the CopyMemory API is running about 600 times slower than a month ago. I did do a Windows Update lately and maybe that is why. In this SO question is seems that Windows Defender is the cause of slowness. Regardless of why the API is much slower, it is unusable if the operations involving the API need to run many times (e.g. millions of times).

Even without the issue mentioned above, CopyMemory API is slower than other alternatives. Since I did not want to use references to msvbvm60.dll which is not available on most of my machines, I decided to create something similar with the GetMemX and PutMemX methods available in the mentioned dll. So, I created a couple of properties (Get/Let) called MemByte, MemInt, MemLong and MemLongPtr using the same ByRef technique that I've used in the WeakReference repository. In short, I am using 2 Variants that have the VT_BYREF flag set inside the 2 Bytes holding the VarType. These 2 Variants allow remote read/write of memory.

Since I couldn't use the same approach I've used for Byte, Integer and Long I've finally decided to go for the Currency approach because it was the cleanest and fastest. A Currency variable is stored using 8 Bytes in an integer format, scaled by 10,000 resulting in a fixed point number. So, it was quite easy to use currency instead of LongLong (see the MemLongPtr Let property).

Another approach is to use a Double but looks absolutely horrendous (and is slower) and needs a second REMOTE_MEMORY variable:

Another decision was to leave the DeRefMem method as a Sub. Consider the current code (excluding the VBA7 declarations):

I would be very grateful for suggestions that could improve the code.
Have I missed anything obvious? Are there any other useful methods that should be part of such a 'Memory' library (e.g. like I've added VarPtrArray and UnsignedAddition)?

Tweeted twitter.com/StackCodeReview/status/1332927306080333828
Added new tag
Link
Cristian Buse
  • 1.8k
  • 6
  • 29
Fixed a typing error
Source Link
Cristian Buse
  • 1.8k
  • 6
  • 29
Loading
Source Link
Cristian Buse
  • 1.8k
  • 6
  • 29
Loading