Why, oh why.

S

schoenfeld1

Michael said:
This is simply not true.

if you read the specs on C# you may think this is so. Even if you read the
specs for CIL you may still believe this is what would happen. But it's not.
The CLR and the JITter could care no less about C# and CIL specs.

It is.

In the String class the the field is declared:

public static readonly string Empty;


and the static constructor is:

static String()
{
string.Empty = "";
string.WhitespaceChars = new char[0x15] {
'\t', '\n', '\v', '\f', '\r', ' ', '\x00a0', '\u2000',
'\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007',
'\u2008',
'\u2009', '\u200a', '\u200b', '\u3000', '\ufeff'
} ;
}
 
S

schoenfeld1

Michael said:
This is simply not true.

if you read the specs on C# you may think this is so. Even if you read the
specs for CIL you may still believe this is what would happen. But it's not.
The CLR and the JITter could care no less about C# and CIL specs.

It is.

In the String class the the field is declared:

public static readonly string Empty;


and the static constructor is:

static String()
{
string.Empty = "";
string.WhitespaceChars = new char[0x15] {
'\t', '\n', '\v', '\f', '\r', ' ', '\x00a0', '\u2000',
'\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007',
'\u2008',
'\u2009', '\u200a', '\u200b', '\u3000', '\ufeff'
} ;
}
 
N

notifications

I am not sure if Brad Adams is talking about v1 or pre service pack (if it
matters anyway) but he is also implying the same arguments as mine:

http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx

| Every
| time you use "" you are allocating a new string instead of using
System.String.Empty.
String literals are interned. Every time you use "" you are receiving
the
exact same string instance as String.Empty!


I see your point, and i also went to the extent of pinning both with a GCHandle
"" and Empty and got the same address of pinned object for both... so Brad
may be wrong after all... I really dont know.

The discurssion started because someone said that using String.Empty as snobbery,
but IMHO I believe it is a good idea cause at least it becomes easier to
read .
As far as memory reuse and allocation it still a good aproach for value types
that you need to use all the time such as System.Drawing.Point.Empty, or
your own value type MyType.Empty (MinValue, MaxValue, etc...) since you can
not default them to null.


Erick Sgarbi
www.blog.csharpbox.com
 
N

notifications

I am not sure if Brad Adams is talking about v1 or pre service pack (if it
matters anyway) but he is also implying the same arguments as mine:

http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx

| Every
| time you use "" you are allocating a new string instead of using
System.String.Empty.
String literals are interned. Every time you use "" you are receiving
the
exact same string instance as String.Empty!

I see your point, and i also went to the extent of pinning both with a GCHandle
"" and Empty and got the same address of pinned object for both... so Brad
may be wrong after all... I really dont know.

The discurssion started because someone said that using String.Empty as snobbery,
but IMHO I believe it is a good idea cause at least it becomes easier to
read .

As far as memory reuse and allocation it still a good aproach for value types
that you need to use all the time such as System.Drawing.Point.Empty, or
your own value type MyType.Empty (MinValue, MaxValue, etc...) since you can
not default them to null.


Erick Sgarbi
www.blog.csharpbox.com
 
J

Jon Skeet [C# MVP]

I am not sure if Brad Adams is talking about v1 or pre service pack (if it
matters anyway) but he is also implying the same arguments as mine:

http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx

No, he's not. He doesn't say *every* time you use "" like you did.
Specifically, he says:

<quote>
it will likely be pulled out of the string intern pool
</quote>

And indeed it's guaranteed to be pulled out of the string intern pool
when you use it for the second time in the same assembly.

There's a very big difference between "it might create one more object
per assembly" (not that it does, I belive) and "it creates a new object
every time you use it".
 
E

Eldar Radovici

I put together a quick test case instantiating both types and looked at
the modules through ILDasm. The only difference is how the strings are
retrieved.

“string sEmpty = "";” is equivalent to “IL_0000: ldstr ""” // pushes a
string object for the metadata string token mdToken

“string sEmpty = string.Empty;” is equivalent to “IL_0000: ldsfld string
[mscorlib]System.String::Empty” // push the value of field on the stack

The important note here is: “The common language infrastructure (CLI)
guarantees that the results 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 next question you might consider is: What's the performance
implication of “string interning?” I'm assuming it goes through some
kind of hash table to ensure that “the same sequence of characters
return precisely the same string object” which means that it's not
instantaneous.

According to Roman Batoukov “string interning” incurs some additional
cost. “Specifically, the memory used to store interned strings is not
freed until the AppDomain is shutdown, and extra time is required to
intern the string (even if the string is already interned).” Note that
this article refers to the .NET Compact Framework version 2.0 but I'm
sure the same “additional cost“ applies elsewhere.
Conclusion, if you care... use String.Empty.

The embedded links are in this post:
http://blog.radovici.com/eldar/archive/2005/08/19/2435.aspx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top