Hello again Peter,
I did catch my name! <grin>
Okay, I'm going to snip a bunch of quotes in order to respond to this
properly, if I take the odd one out of context, I apologize, because I
see this as an interesting discussion versus a debate, really.
is say 4 times faster, varies slightly with string length but not by
much
Good, this where we start, there's a reason to explore this
opportunity, eh.
I notice you ReDim the bArr() to 2 x string length, that works but doesn't
seem necessary.
It's absolutely necessary if you're going to go straight from Unicode,
to ASCII, to Byte Array, which you can do if you dump StrConv(). And
remember that 4x! See the following:
http://vb.mvps.org/hardcore/html/whatisunicode.htm
However I don't regard StrConv as a significant overhead. Even in a long
loop I find with doing all the other stuff the overall difference is
trivial.
I thought we just said 4x? It's significant in terms of % performance,
isn't 4x significant? 4x can't be trivial, can it? I'd have to
argue that this is the big gainer, last time around we were diddling
around with inline vs. modulated... Small potatoes, that actually
convoluted the algorithm, with all due respect... Don't diddle, make
the algorithm better, and this is a very good start.
Again, this is to make the gain on smaller strings, on longer strings
you won't see it as much.... And, we should use a timer on varying
strings, in terms of length, to be sure, we got into some trouble in
our last thread on this subject with conjecture...
But - there's a nasty catch if avoiding strConv when it comes to processing
char's in the range chr(128 - 159), possibly others in non standard
char-sets, look at the dump in this range -
IOW, if changing those bytes in a Step 2 loop the return will be wrong.
It looks like it's wrong to me, either way... Why did you add one to
the element in the loop? Check out the dump in this procedure:
Sub foo()
Dim strIn As String, strOut As String, s As String
Dim bArr() As Byte
Dim i As Long, rw As Long
Application.ScreenUpdating = True
For i = 32 To 255
strIn = strIn & ChrW$(i)
Next
Let bArr = strIn
Let strOut = bArr
For i = 1 To Len(strIn)
Let s = Mid$(strIn, i, 1)
Let Cells(i, 1) = Asc(s)
Let Cells(i, 2) = s
Next
Let rw = 1
For i = LBound(bArr) To UBound(bArr) Step 2
Let Cells(rw, 3) = bArr(i)
Let Cells(rw, 4) = ChrW$(bArr(i))
Let rw = rw + 1
Next
Application.ScreenUpdating = True
End Sub
And this one:
Sub bar()
Dim strIn As String, strOut As String, s As String
Dim bArr() As Byte
Dim i As Long, rw As Long
Application.ScreenUpdating = True
For i = 32 To 255
strIn = strIn & ChrW$(i)
Next
Let bArr = StrConv(strIn, vbFromUnicode)
Let strOut = bArr
For i = 1 To Len(strIn)
Let s = Mid$(strIn, i, 1)
Let Cells(i, 1) = Asc(s)
Let Cells(i, 2) = s
Next
Let rw = 1
For i = LBound(bArr) To UBound(bArr)
Let Cells(rw, 3) = bArr(i)
Let Cells(rw, 4) = ChrW$(bArr(i))
Let rw = rw + 1
Next
Application.ScreenUpdating = True
End Sub
It seems that you were working with the wrong element, start with 0 and
go every other element. Or am I missing something? Either way, it
doesn't look like StrConv() is going to bail you out on those
Chars...
By the way, and this is part of the point, these days I have a serious
distaste for anything resembling the following:
For i = 32 To 255
strIn = strIn & ChrW$(i)
Next
I replicated it for the sake of addressing the question, but this is
slow!! It's String Ops like this that make VB[A] appear to be very
slow, once you get to ~40 concatenations this begins to degrade in a
way where you should consider doing something else. See the following:
http://msdn.microsoft.com/library/en-us/dngenlib/html/heap3.asp
"Slowdown as a result of frequent allocs and reallocs. This is a very
common phenomenon when you use scripting languages. The strings are
repeatedly allocated, grown with reallocation, and freed up. Don't do
this. Try to allocate large strings, if possible, and use the buffer.
An alternative is to minimize concatenation operations."
Note the 'Don't do this' part. Much like using ReDim Preserve or Union
in a loop, concatenating in a haphazard fashion is pretty hard on your
resources, more important on longer procedures... If the point is to
build one seriously fast algorithm, concatenating in a Loop need not
apply. This is why we use an array, with a buffer, except even better
in this case, we know the size of the array, Chars * 2.
You successfully sold me the Byte array + StrConv combination and not sure
I'm ready to cash in the StrConv!
Get ready!! I'm not selling anything, mind you. Never was, actually...
Please go about this as you wish, I'm simply sharing my experiences
with Excel and VB[A]...
StrConv() is handy, expensive, but handy, no doubt about it. And like
in the original thread you just mentioned, I used it as a starting
point, it's easier to work with an array that isn't *2. But, if the
goal is to write something with some serious chops, then dump it,
because you can, and you'll be rewarded!
Regards,
Nate Oliver