String Literal

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Where is a string literal (say "test") stored, the stack or managed heap? I
know a string variable is stored in the managed heap.

In determining the toolbar button clicked in the button clicked event, which
is more efficient:

Select Case tbrMain.Buttons.IndexOf(e.Button)
Case 0
...
Case 1
...

or

Select Case e.Button.Tag
Case "Test1"
...
Case "Test2"

If the string literals are in the managed heap, it seems to me the latter
(no boxing occurs) is more efficient.
 
B Spencer said:
Where is a string literal (say "test") stored, the stack or managed heap? I
know a string variable is stored in the managed heap.

In determining the toolbar button clicked in the button clicked event, which
is more efficient:

Select Case tbrMain.Buttons.IndexOf(e.Button)
Case 0
...
Case 1
...

or

Select Case e.Button.Tag
Case "Test1"
...
Case "Test2"

If the string literals are in the managed heap, it seems to me the latter
(no boxing occurs) is more efficient.

Hi,

Remember that ildasm.exe is your friend. You can find ildasm.exe in
"...\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\".

Say you have a method like this:

void foo()
{
string localVar = "literal string";
System.Console.WriteLine(localVar);
}

Use can use ildasm to "disassemble" the resulting exe/dll to see what is
going on at the IL (intermediate language) level - this is .NET's equivalent
of assembly language.

..method private hidebysig instance void foo() cil managed
{
// Code size 13 (0xd)
.maxstack 1
.locals init ([0] string localVar)
IL_0000: ldstr "Const string1" <== Look at this, what
does ldstr do??
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call void [mscorlib]System.Console::WriteLine(string)
IL_000c: ret
} // end of method Class1::foo

You can find an IL reference doc in "...\Microsoft Visual Studio .NET
2003\SDK\v1.1\Tool Developers Guide\docs", entitled "Partition III CIL.doc".
Looking up the ldstr instruction we find that ldstr loads a literal string
(which is pretty much obvious right?). But if we look at the actual
explanation for the ldstr instruction we find this:

The ldstr instruction pushes a new string object representing the literal
stored in the metadata as string (that must be a string literal).

The ldstr instruction allocates memory and performs any format conversion
required to convert from the form used in the file to the string format
required at runtime. The CLI guarantees that the result of two ldstr
instructions referring to two metadata tokens that have the same sequence of
characters return precisely the same string object (a process known as
"string interning").


So, the literal string is stored in the metadata and memory is allocated
(in the heap) for it. And notice that there will only EVER be ONE instance
of that string in memory.

I hope this sheds a bit of light onto the subject!

-TJ
 
* =?Utf-8?B?QiBTcGVuY2Vy?= said:
In determining the toolbar button clicked in the button clicked event, which
is more efficient:

Select Case tbrMain.Buttons.IndexOf(e.Button)
Case 0
...
Case 1
...

or

Select Case e.Button.Tag
Case "Test1"
...
Case "Test2"

Use this:

\\\
Private Sub ToolBar1_ButtonClick( _
ByVal sender As Object, _
ByVal e As ToolBarButtonClickEventArgs _
) Handles ToolBar1.ButtonClick
Select Case True
Case e.Button Is Me.ToolBarButton1
 
As far as I can see no boxing occurs in the first case either and comparing
integers is always preferable to comparing strings in terms of performance.

Regards, Jakob.
 
Jakob Christensen said:
As far as I can see no boxing occurs in the first case either and comparing
integers is always preferable to comparing strings in terms of performance.

Except that's not the only difference - there's the call to IndexOf as
well.

I suspect that the JIT compiler *may* be able to compile more efficient
code for a switch/case on strings (where it could use binary search by
hashcode, for instance) than the IndexOf call can manage.

I agree about the lack of boxing though.
 
Back
Top