If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

SafeArrayCopy SLOWER than iterating string array!

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) :

' 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())
Else
' Raise a Type Mismatch error.
Err.Raise win.VBErrorConst.eeTypeMismatch
End If

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?

Re: SafeArrayCopy SLOWER than iterating string array!

Michael -

I fully understand that APIs can be slower than VB code, which is why I bothered
to do the test. However, as a general rule, the hackers who wrote API code
probably have more experience with them than me, and probably know the "guts"
of the routines, and as a result are more likely to have a faster way to
use their more primitive routines than me.

I was just somewhat surprised that my code was 5.5 times faster than theirs.
I would have expected at least something comparable with mine. I am wondering
whether there is something in my code that is bound to slow the API routine
down.

Re: SafeArrayCopy SLOWER than iterating string array!

Michael -

I fully understand that APIs can be slower than VB code, which is why I bothered
to do the test. However, as a general rule, the hackers who wrote API code
probably have more experience with them than me, and probably know the "guts"
of the routines, and as a result are more likely to have a faster way to
use their more primitive routines than me.

I was just somewhat surprised that my code was 5.5 times faster than theirs.
I would have expected at least something comparable with mine. I am wondering
whether there is something in my code that is bound to slow the API routine
down.

Re: SafeArrayCopy SLOWER than iterating string array!

Hi Mark,

When I test the SafeArrayCopy and SafeArrayCopyData functions here, they all
take about the same time as VB's assignment (VB6) or VB's For..Next methods,
for large arrays of strings. (see my code below).

A couple of things.. you don't need a type library to get the pointer for a
string array. See my code below, and/or see July's VBPJ for more details.
Also the safearraycopy is most probably the same as VB's assignment, whereas
safeArrayCopyData would be equivalent of For.. Next loop.

It could be your timings weren't done on a random basis, and hence the
sequence of events favoured one method over the other. Try running the code
I have posted, and you will see which ever method get's called first will
have the fastest time by far but only that one time.. on subsequent calls
all methods tend to be about the same, although the For..Next method seems
to be one or two percent slower.

If CopyMethod Then
If CopyMethod And &H2 Then
If CopyMethod And &H1 Then
'mForNext
lngUb = UBound(asIn)
ReDim asOut(lngUb)
For i = 0 To lngUb
asOut(i) = asIn(i)
Next i
CopyArray = "VBForNext"
Else
'mVbAssign
asOut = asIn
CopyArray = "VBAssign"
End If

Re: SafeArrayCopy SLOWER than iterating string array!

Hi Mark,

When I test the SafeArrayCopy and SafeArrayCopyData functions here, they all
take about the same time as VB's assignment (VB6) or VB's For..Next methods,
for large arrays of strings. (see my code below).

A couple of things.. you don't need a type library to get the pointer for a
string array. See my code below, and/or see July's VBPJ for more details.
Also the safearraycopy is most probably the same as VB's assignment, whereas
safeArrayCopyData would be equivalent of For.. Next loop.

It could be your timings weren't done on a random basis, and hence the
sequence of events favoured one method over the other. Try running the code
I have posted, and you will see which ever method get's called first will
have the fastest time by far but only that one time.. on subsequent calls
all methods tend to be about the same, although the For..Next method seems
to be one or two percent slower.

If CopyMethod Then
If CopyMethod And &H2 Then
If CopyMethod And &H1 Then
'mForNext
lngUb = UBound(asIn)
ReDim asOut(lngUb)
For i = 0 To lngUb
asOut(i) = asIn(i)
Next i
CopyArray = "VBForNext"
Else
'mVbAssign
asOut = asIn
CopyArray = "VBAssign"
End If