Good day!

Being one of those people who is obsessed with maximising the performance of
repetitive operations, I was looking for alternative ways to copy one string
array to another in VB5. I have previously been writing a functions to
convert a Variant containing a String Array to a String Array, and had used
the SafeArrayCopy function. This then got me thinking that maybe this
function would be a quicker way to copy large string arrays, as happens a
lot in our code. After much messing about, I came up with the following
code, which requires a type library for the VarPtrStringArray() function
(see MSDN Knowledge Base Q199824 - HOWTO: Get the Address of Variables in
Visual Basic) :


Option Explicit

Private Declare Function SafeArrayCopy Lib "oleaut32.dll" ( _
ByVal psa As Long, _
ByVal ppsaOut As Long) As Long

Private Type VARIANT_PTR
vt As Integer
reserved1 As Integer
reserved2 As Integer
reserved3 As Integer
ptr As Long
filler(1 To 4) As Byte
End Type

Public Sub GVariantToStringArray(ByRef v As Variant, _
ByRef s() As String)
' Purpose: Retrieves a string array from a variant.
' Inputs: v
' Outputs: s()
' In/Outs: <None>
' Created: 12/06/2000: MAB
Dim udtVariant As VARIANT_PTR

' Take a copy of the variant to the variant structure.
win.CopyMemory udtVariant, v, 16
' Only allow variant string arrays.
If udtVariant.vt = (vbString Or vbArray) Then
' Ensure that any strings in existance are released.
Erase s()
' Copy the array in the variant over to s().
SafeArrayCopy udtVariant.ptr, VarPtrStringArray(s())
' Raise a Type Mismatch error.
Err.Raise win.VBErrorConst.eeTypeMismatch
End If

End Sub

Public Sub GCopyStringArray(ByRef asSource() As String, _
ByRef asDestination() As String)
' Purpose: Copies the string array, asSource, to asDestination.
' Inputs: asSource
' Outputs: asDestination
' In/Outs: <None>
' Created: 12/06/2000: MAB
Dim ptr As Long

' Destroy asDestination.
Erase asDestination

' Get a pointer to the pointer to asSource.
win.CopyMemory ptr, ByVal VarPtrStringArray(asSource), 4
' Copy data from asSource to asDestination.
SafeArrayCopy ptr, VarPtrStringArray(asDestination)

End Sub


Well, the GCopyStringArray routine works, but in tests, it is approximately
5.5 times slower than simply Redim'ing a new string array, and then copying
strings between the old and new arrays. Most perplexing. Can anybody
explain this big difference in speed?


Mark Alexander Bertenshaw
Prime Response