Can anyone give me (or point me to) a brief overview of what happens when a
new string variable is dimensioned, when it is assigned a value, and when it
goes out of scope? Also, how does this compare to what happens with fixed
length strings?
How about the advantages/disadvantages of storing strings in memory in their
StrConv(vbFromUnicode, ...) form.
Oh yeah, I also noticed it is possible to replace part of a string using
Mid$(...) = ... and I assume this means the characters are just copied into
the string's existing memory space without having to create a new string and
drop the original. This would seem to provide some of the same benefits as
using byte arrays without some of the corresponding complications (i.e.
having to create a custom data type to make an array of variable-length
arrays of byte).
Dev Ashish wrote in message
<5dls4.6714$PA2.6...@bgtnsc06-news.ops.worldnet.att.net>...
>Steve, Michael would be the best person to answer this, but I just wanted
to
>throw in what I've learned (aka guesswork)... btw Bruce McKinney's 3rd
>article "Strings the OLE way" or similar topic in MSDN covers this in much
>more detail.
>
>VBA strings, BSTRs (Unicode), are just pointers to Unicode chars in memory.
>Manipulating strings in VBA calls the various Sys* API functions
internally,
>like SysAllocString, SysReallocString etc. When you instantiate a string in
>VBA, internally SysAllocString is called which allocates a memory space and
>copies the characters to that space (fixed len string). When you assign a
>value to a string, VBA will call SysReallocStringLen to allocate a new BSTR
>and copy the content across. When the variable goes out of scope, VBA
calls
>SysFreeString to free up the resources associated with the string.
>
>Because of BSTR allocation/deallocation for each operation (for example,
>when you concatenate using ampersand, VBA has to allocate temp. buffers for
>both the strings before assigning it to the variable), string operations
are
>generally amongst the slowest in VBA. (btw for lurkers, vbNullString is not
>the same as a zero length string "").
>Keeping strings in byte arrays might be faster compared to dealing with
>large strings directly. Same holds true for numeric operations, for example
>if Asc(strSomething)=34 instead of if strSOmething="'").
>You have to watch for the internal ANSI<->Unicode conversion VBA does, and
>try to avoid it as much as possible.
>Fixed length strings are generally slower than variable length strings.
This
>is because VBA functions all work with variable length strings only.
>Therefore when you pass a fixed length string to a VBA function, VBA must
>internally first convert the FL string to a normal variable length string,
>and convert it the other way around on return.
>Using strComp to compare strings is faster than doing strA=strB.
>
> -- Dev
>
>"Steve Jorgensen" <nos...@nospam.com> wrote in message
>news:8Lks4.14030$yn3.1...@news1.teleport.com...
>: I am trying to figure out the relative cost/benefit of different string
>:
>:
>
>
--
?MichKa
(insensitive fruitarian)
random junk of dubious value, a multilingual website, the
54-language TSI Form/Report to Data Access Page Wizard,
and lots of replication "stuff" at http://www.trigeminal.com/
?
"Steve Jorgensen" <nos...@nospam.com> wrote in message
news:JOls4.14155$yn3.1...@news1.teleport.com...
Musing out loud:
For heavily reused code where strings are usually written only once, it
sounds like I may want to look at using medium-large strings as allocation
units to contain several "strings", keeping a list of starting points and
lengths of "strings" within it, and using Mid$ to store/retrieve contents.
Of course, this would prohibit passing contents by reference to avoid
creating new string objects and copying character data, but this is not
always possible anyway (i.e. getting a string from object with Property Get
<propname>(<indexparam>) As String ).
Michael (michka) Kaplan wrote in message ...
BTW: I don't know if this test is conclusive, but I tried to see if an
unused string variable allocates space for character data as follows:
Sub test()
Dim a As String
Debug.Print StrPtr(a)
Debug.Print StrPtr(vbNullString)
a = ""
Debug.Print StrPtr(a)
a = "x"
Debug.Print StrPtr(a)
a = vbNullString
Debug.Print StrPtr(a)
End Sub
The result I got was as follows:
0
0
4666880
154150852
0
If I understand correctly, this indicates that an unused string variable
actually has a null pointer (not what I thought or what Dev stated) as does
vbNullStr, but it has space allocated to it when it is assigned any value
including "". Aparently, the string can be unallocated by assigning
vbNullString to it which I did not even know was meaningful before doing
this experiment.
David W. Fenton wrote in message <8EE1FF2F2df...@news1.bway.net>...
>d...@nomail.please (Dev Ashish) wrote in
><5dls4.6714$PA2.6...@bgtnsc06-news.ops.worldnet.att.net>:
>
>>btw for lurkers, vbNullString is not
>>the same as a zero length string ""
>
>Um, eh? What?
>
>In the immediate window:
>
>?vbnullstring = ""
>True
>
>?"" = vbnullstring
>True
>
>MichKa's been saying it's better to use vbNullString for comparison
>than "", and I've been doing it religiously. It never fails. As far
>as I can see in anything I do (and I use it a lot), it really is
>the same, except for the performance issue that MichKa refers to.
>
>I've always hated the name, though.
>
>--
>David W. Fenton http://www.bway.net/~dfenton
>dfenton at bway dot net http://www.bway.net/~dfassoc
VBA strings, BSTRs (Unicode), are just pointers to Unicode chars in memory.
Manipulating strings in VBA calls the various Sys* API functions internally,
like SysAllocString, SysReallocString etc. When you instantiate a string in
VBA, internally SysAllocString is called which allocates a memory space and
copies the characters to that space (fixed len string). When you assign a
value to a string, VBA will call SysReallocStringLen to allocate a new BSTR
and copy the content across. When the variable goes out of scope, VBA calls
SysFreeString to free up the resources associated with the string.
Because of BSTR allocation/deallocation for each operation (for example,
when you concatenate using ampersand, VBA has to allocate temp. buffers for
both the strings before assigning it to the variable), string operations are
generally amongst the slowest in VBA. (btw for lurkers, vbNullString is not
>btw for lurkers, vbNullString is not
>the same as a zero length string ""
Um, eh? What?
I would think that's conclusive enough... :-)
-- Dev
Actually, it's quite possible to set a string to vbNullString in VBA and
it's actually faster than assigning the var to a ZLS (""). It's not just
for DLLs. If you just dim a string var, you get a null pointer by default.
The moment you assign _anything_ to the string, including a ZLS, VBA has to
go through allocation and you get a valid StrPtr. A ZLS, in Unicode, is a
two chars wide space filled with vbNullChar. So if you did a RTLMoveMemory
on strPtr("") for two chars, you'll get a ZLS back. A vbNullString doesn't
even have this space allocated, the pointer itself is "invalid". That's
basically the difference.
: Anyway, this
: means an array of strings can be very costly even if most of the elements
: are never explicitly used, right (why does a string with a stored length
: need a null termination character!)?
That's no always true. In VBA, an array of strings is essentially an array
of string descriptors (or VarPtr(str)) which is always contiguous (longs),
even though the addresses point to non-contiguous segments. So when you're
accessing strings in arrays, you're sequentially going over a continuous
block of memory, 4 bytes at a time and then jumping over to whichever
address the descriptor is pointing to.
As for a null termination character, that's the definitioin of OLECHAR/BSTR,
every string has a trailing vbNullChar (or two, if you think in terms of
Unicode) as that's the "identification" of where the string terminates.
:
: Musing out loud:
: For heavily reused code where strings are usually written only once, it
: sounds like I may want to look at using medium-large strings as allocation
: units to contain several "strings", keeping a list of starting points and
: lengths of "strings" within it, and using Mid$ to store/retrieve contents.
: Of course, this would prohibit passing contents by reference to avoid
: creating new string objects and copying character data, but this is not
: always possible anyway (i.e. getting a string from object with Property
Get
: <propname>(<indexparam>) As String ).
Another option would be to pass bytes or a byte array, it should be faster
instead of eval'ing individual chars. Yes, using Mid$ to retrive/change
string constant than iterating over the string is faster.
-- Dev
See Steve's post, David. StrPtr returns the conclusive evidence for you on
vbNullString="". Yes vbNullString is better for doing the ZLS comparison,
but what's even faster is to do a Len(str)=0.
Moreover, the comparison, internally to VBA, is not the same as for a ZLS,
VBA will allocate a two byte space before doing the comparison. WHen you
compare to vbNullString, all VBA has to do is to check if the first var is
pointing to an invalid address (zero).
-- Dev
I see. That's not what I understood you to be saying previously. What you
are saying here seems to match the results of my experiment (reply to D.F.).
vbNullString is a Null pointer
"" is a pointer to Null
:-)
--
?MichKa
(insensitive fruitarian)
random junk of dubious value, a multilingual website, the
54-language TSI Form/Report to Data Access Page Wizard,
and lots of replication "stuff" at the (no scripts required!)
http://www.trigeminal.com/
?
"Steve Jorgensen" <nos...@nospam.com> wrote in message
news:74Ds4.15543$yn3.1...@news1.teleport.com...
We don't care
--
?MichKa
(insensitive fruitarian)
random junk of dubious value, a multilingual website, the
54-language TSI Form/Report to Data Access Page Wizard,
and lots of replication "stuff" at the (no scripts required!)
http://www.trigeminal.com/
?
"Steve Jorgensen" <nos...@nospam.com> wrote in message
news:JdKs4.16298$yn3.1...@news1.teleport.com...
>
> David W. Fenton wrote in message
<8EE36D77dfe...@news1.bway.net>...
> We don't care
>
>