Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What is basic anatomy/overhead of string variables

29 views
Skip to first unread message

Steve Jorgensen

unread,
Feb 21, 2000, 3:00:00 AM2/21/00
to
I am trying to figure out the relative cost/benefit of different string
handling techniques in code, and I don't know enough about the anatomy of a
string in VB to figure it out.

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.

Steve Jorgensen

unread,
Feb 21, 2000, 3:00:00 AM2/21/00
to
Thanks. Do you know if string space is allocated (outside the BSTR
structure itself) when a string is first dimensioned and still has a zero
length? In other words, does VB allocate zero-length blocks of memory for
strings with all the associated clean-up costs, or are unused string
variables (i.e. in partially used arrays of strings) fairly low cost since
clean-up must merely determine that the string has no memory block to
deallocate?

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

>:
>:
>
>

Michael (michka) Kaplan

unread,
Feb 21, 2000, 3:00:00 AM2/21/00
to
If the string is ever allocated, then it takes up the space. Thats is what
Dev is referring to by calling vbNullstring not the same as "". One is a
null pointer, the other is a pointer to a zero-length string and a null
character. The former needs no deallocation, the latter does.

--
?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...

Steve Jorgensen

unread,
Feb 21, 2000, 3:00:00 AM2/21/00
to
Then it is impossible to dimension a new string without allocating space for
its characters. I don't think it's even possible to set a string equal to
VBNullString in Access; it's only there for passing to DLLs. 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!)?

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 ...

Steve Jorgensen

unread,
Feb 21, 2000, 3:00:00 AM2/21/00
to
Hmm, according the the help, vbNullString is a null pointer used for passing
a null pointer to a DLL, and is not the same (at least in that case) as an
empty string.

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

Dev Ashish

unread,
Feb 22, 2000, 3:00:00 AM2/22/00
to
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

David W. Fenton

unread,
Feb 22, 2000, 3:00:00 AM2/22/00
to
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?

Dev Ashish

unread,
Feb 22, 2000, 3:00:00 AM2/22/00
to

"Steve Jorgensen" <nos...@nospam.com> wrote in message
news:3Uos4.14381$yn3.1...@news1.teleport.com...
: 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)
: 0
: 0
: 4666880


I would think that's conclusive enough... :-)

-- Dev

Dev Ashish

unread,
Feb 22, 2000, 3:00:00 AM2/22/00
to

"Steve Jorgensen" <nos...@nospam.com> wrote in message
news:iJos4.14372$yn3.1...@news1.teleport.com...
: Then it is impossible to dimension a new string without allocating space

for
: its characters. I don't think it's even possible to set a string equal to
: VBNullString in Access; it's only there for passing to DLLs.

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

Dev Ashish

unread,
Feb 22, 2000, 3:00:00 AM2/22/00
to

"David W. Fenton" <dXXXf...@bway.net> wrote in message
news: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.
:


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

Steve Jorgensen

unread,
Feb 22, 2000, 3:00:00 AM2/22/00
to

Dev Ashish wrote in message ...
>
<snip>

>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.
>


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

Michael (michka) Kaplan

unread,
Feb 22, 2000, 3:00:00 AM2/22/00
to
Since a ZLS ends up being a pointer to a Null character, and since
vbNullString is known as a Null pointer.... the difference between the two
is:

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...

Steve Jorgensen

unread,
Feb 22, 2000, 3:00:00 AM2/22/00
to

David W. Fenton wrote in message <8EE36D77dfe...@news1.bway.net>...
>forme...@spamless.trigeminal.spamless.com (Michael \(michka\)
>Kaplan) wrote in <uPbZ81Xf$GA.257@cpmsnbbsa05>:

>
>>Since a ZLS ends up being a pointer to a Null character, and since
>>vbNullString is known as a Null pointer.... the difference between
>>the two is:
>>
>>vbNullString is a Null pointer
>>"" is a pointer to Null
>
>But how do I get a ticket to ride?

>
>--
>David W. Fenton http://www.bway.net/~dfenton
>dfenton at bway dot net http://www.bway.net/~dfassoc

We don't care

David W. Fenton

unread,
Feb 23, 2000, 3:00:00 AM2/23/00
to

Michael (michka) Kaplan

unread,
Feb 23, 2000, 3:00:00 AM2/23/00
to
Actually, my baby 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
>
>

0 new messages