String.Empty vs. string literal

G

Guest

Anybody have a definitive, backable answer to which version performs better:
String.Empty vs. ""?

Given:
private void TestEmptyObject ( string value )
{
int nCt = 0;
if (value == String.Empty)
++nCt;
}

My experiments show that they are equivalent except for String.Empty is
loaded through ldsfld and "" is loaded through ldstr. They both eventually
call String.Equality(string, string) which will treat them the same.

My rule is to use "" because to me it is clearer to read. Anybody have a
really good reason why String.Empty should be used instead? Of course I'm
only talking about a single language here. Understandably String.Empty is
useful when trying to represent an empty string in a (programming) language
neutral way but this is rare.

Thanks,
Michael Taylor - 4/18/05
 
M

Mehdi

Anybody have a definitive, backable answer to which version performs better:
String.Empty vs. ""?

Given:
private void TestEmptyObject ( string value )
{
int nCt = 0;
if (value == String.Empty)
++nCt;
}

I won't answer you question since i haven't a clue about that but, as a
side note, Microsoft seems to recommand using
if (value.Length == 0)
instead of
if (value == String.Empty)

Run FxCop on your code and it will tell you that.
My rule is to use "" because to me it is clearer to read.

My rule is to use String.Empty because to me it's clearer to read (it says
in plain English what i am trying to do). Just a matter of taste really.
 
G

Guest

I agree completely. I always use Length in comparison for empty strings.
The IsNullOrEmpty method in 2.0 is my new best friend. I too use FxCop to
detect these issues but that wasn't really the point of my posting. I used
equality testing as a benchmark only. My main interest is when dealing with
assignment of empty strings.

Thanks,
Michael Taylor - 4/18/05
 
D

Daniel O'Connell [C# MVP]

I won't answer you question since i haven't a clue about that but, as a
side note, Microsoft seems to recommand using
if (value.Length == 0)
instead of
if (value == String.Empty)

Run FxCop on your code and it will tell you that.

And the people who wrote FxCop should be shot for putting that rule in as it
currently is. You do realize that

if (value.Length == 0)
and
if (value == String.Empty)

have two entirely different semantic meanings, don't you? IsNullOrEmpty
helps with this to some degree.
The savings are close to insignificant if you are not writing an xml parser
or something else that deals only in text, the decrease in code clarity
noticable, and the blind faith in that moronic tool annoying.

I wish the people who wrote FxCop would have just kept it to themselves.
 
G

Guest

I disagree with your assessment of FxCop. Evidently enough people like it
because it is part of VS 2005. I do agree that blindly following its rules
is not the correct answer but they address that themselves in the
documentation for the tool. It is of primary use to library writers like
myself that do not know ahead of time who their audience will be. It does
identify a lot of "design" flaws that are commonly made, such as new
protected members in a sealed class or non-private constructors in static
only classes. Some of these things the compiler could certainly figure out
but "invisibly" making such a change could have unforeseen consequences.
Reflection comes to mind here. Of course it also is overjealous about
localization and IFormatProvider. I just turn these off. People have been
using code review tools for decades. FxCop is just Microsoft's free version.

I don't follow your comment on (value.Length == 0) and (value ==
String.Empty) not being equal. They are not "code-wise" equal (one being an
int compare and the other calling a native comparer for the interned strings)
but they are semantically equal. In both cases if the string is empty they
are true and if the string is not empty they are false. The only real
difference is when the string is null. That is why the current methodology
recommends (value == null) || (value.Length == 0). In 2.0 IsNullOrEmpty will
remove the need for this conditional.

Thanks,
Michael Taylor - 4/19/05
 
D

Daniel O'Connell [C# MVP]

TaylorMichaelL said:
I disagree with your assessment of FxCop. Evidently enough people like it
because it is part of VS 2005. I do agree that blindly following its
rules
is not the correct answer but they address that themselves in the
documentation for the tool. It is of primary use to library writers like

Documenation isn't enough, if you take the number of people who read the
documentation and the number of people who just jump in and use it, I'd bet
you would have a difficult time fitting the ratio between the two in this
message. People don't read it and assume that the defaults are "how its
supposed to be".

I personally think FxCop has had the dubious honor of recommending things to
people that make no sense in the situation the person is actually in. Take
this Length == 0 thing, its stupid. Why? Because you have to do two
comparisons and make the expression a little more complex on the author and
subsequent readers for performance gains that will, in probably more than
99% of libraries, have as much visible effect as an ounce of salt would have
in Lake Michigan.

Over a benchmark of 1 million comparisons x == "" is not significantly
slower(about 70 milliseconds on a 400mhz, about 30 on my 2.0ghz), a big
chunk of time if you are writing a high-throughput xml parser or an html
renderer, but if you are just checking nameString to make sure someone typed
it in correctly, its not going to give you anything. Yet FxCop recommends
it, people follow it religiously, and you end up with oh so much more of
that premature optimization that performance yonks are always talking about.
Two comparisons coded to save less than a microsecond per comparison on a
400 mhz processor is ridiculous.

Of interest, if already interned, the fastest way to actually compare two
strings is by doing a reference comparison ( (object)x == (object)"" ). I'm
seeing an average of 20-30 milliseconds per 1 million comparisons that way
on my 2ghz.
myself that do not know ahead of time who their audience will be.
identify a lot of "design" flaws that are commonly made, such as new
protected members in a sealed class or non-private constructors in static
only classes. Some of these things the compiler could certainly figure
out
but "invisibly" making such a change could have unforeseen consequences.
Reflection comes to mind here. Of course it also is overjealous about
localization and IFormatProvider. I just turn these off. People have
been
using code review tools for decades. FxCop is just Microsoft's free
version.

That doesn't change that the tool recommends things that don't make sense
all too often and that it comes across as a verbatim "Microsoft
Recommendation." Advice given that is taken as a command is almost always
badly put advice.

The help on design flaws is nice, but I still think they could have done a
*MUCH* better job on the rules enabled by default and explaining themselves.

A tools worth is the net difference of those it helps and those it harms.
The help on design flaws doesn't outweigh the number of bad perceptions
FxCop has spread throughout developers in my mind.

I don't follow your comment on (value.Length == 0) and (value ==
String.Empty) not being equal. They are not "code-wise" equal (one being
an
int compare and the other calling a native comparer for the interned
strings)
but they are semantically equal. In both cases if the string is empty
they
are true and if the string is not empty they are false. The only real
difference is when the string is null. That is why the current
methodology
recommends (value == null) || (value.Length == 0). In 2.0 IsNullOrEmpty
will
remove the need for this conditional.

As a note, value == "" is *NOT* the same as (value == null) || (value.Length
== 0), it is closer to (value != null) && (value.Length == 0). You basically
have two different concepts

one set is

value == ""
and
value != null && value.Length == 0

these are true only if the value *is* ""(string.Empty), but not if it is
null or "a" or anything else

the other set,
value == null || value == ""
and
string.IsNullOrEmpty(value)

are true if value is ""(string.Empty) *OR* if it is null.

IsNullOrEmpty still has a different meaning than x == "", unquestionably.
The difference between null and blank is as important as the difference
between blank and "banana".

I also, personally, think that

if (x != null && x.Length == 0)

is pretty ugly, harder to type, offers more points of error, and more
complex to understand than just x == "" or x == string.Empty, and shouldn't
be used just to make FxCop happy or for non-existant performance reasons.
IsNullOrEmpty doesn't solve the problem as it is really an answer for a
different problem.

If there is no performance need, just a human cost, what sense does it make?
 
G

Guest

We'll have to agree to disagree. I feel, like many others, that FxCop and
related tools are a wonderful addition to our toolsets. Especially since I
can create company-mandated requirements and enforce them as well. I concur
that each rule should be evaluated to determine if it applies (that is why
they have exclusions) but I think the lump decision that FxCop gives bad
"commands" is wrong. Let everybody else decide how and if they want to use
the tool. That wasn't the point of this posting anyway.

I'm not sure about your numbers because I haven't looked but I use to write
real-time compilers for a living and I know that if I put a string comparison
in there QA would hunt me down. Integer comparisons are always faster. In
the case of checking for null or length == 0 there will be 1 or 2 int
comparisons and 1 callvirt. Given that callvirt would hopefully be optimized
out when JITed this leaves 1 to 2 int comparisons.

In the case of str == "" and str == String.Empty they both call op_Equality
which calls Equals which finally does a reference comparison followed by the
instance equals. Therefore I would assume that if the string is empty then
all methods would compare about equal but if the string was not empty (the
general case) using these 2 statements would be far more expensive since
there are 3 method calls (possibly 1 with JITing), 1 comparison and a native
function call. My simple testcases seem to agree. When using a non-empty
string NullOrEmpty is the same or faster than String.Empty. When using an
empty string they all compare about the same.

Thanks for your input. Maybe there are some others that will have some more
insight.

Michael Taylor - 4/20/05
 
G

Guest

One thing that I should clarify is that a null string and an empty string are
different. However in most code a null string is equivalent to an empty
string. A more realistic example of what I do is:

void Foo ( string value )
{
if (value == null)
...
value = value.Trim();
if (value.Length == 0)
...

...
}

So the question becomes are any of these methods really any better than the
other and why: value == "", value == String.Empty, value.Length == 0.

Thanks,
Michael Taylor - 4/20/05
 
D

Daniel Billingsley

I'm not sure about your numbers because I haven't looked but I use to write
real-time compilers for a living and I know that if I put a string comparison
in there QA would hunt me down. Integer comparisons are always faster. In
the case of checking for null or length == 0 there will be 1 or 2 int
comparisons and 1 callvirt. Given that callvirt would hopefully be optimized
out when JITed this leaves 1 to 2 int comparisons.

He didn't say the .Length approach wasn't faster. He said the performance
difference is completely inconsequential in 99% of applications.
Absolutlely correct. Even if the application is doing it a few thousand
times it's not something any user is going to notice, with the possibility
of the few exceptions as he noted.

However, that's not to say that all else being equal we shouldn't choose the
more performant option. The question is when there's a tradeoff between
readability and performance.

[From other post by Taylor]
So the question becomes are any of these methods really any better than the
other and why: value == "", value == String.Empty, value.Length == 0.

And the point is that "better" doesn't mean simply more performant by 20
microseconds. That should come way behind readability in most cases.

Of course all of this assumes you find something=="" more readable than
something.Length==0, which I'd argue is a matter of personal taste.
 
D

Daniel O'Connell [C# MVP]

TaylorMichaelL said:
One thing that I should clarify is that a null string and an empty string
are
different. However in most code a null string is equivalent to an empty
string. A more realistic example of what I do is:

void Foo ( string value )
{
if (value == null)
...
value = value.Trim();
if (value.Length == 0)
...

...
}

Of some interest, in the vast majority of my code your method would break me
pretty badly. I draw a distinction between blank, null, and " " in almost
every circumstance. In compilers the three can be close to equal, but in
data based apps the three are as different as each message on this board.
Your methodology wouldn't work for me or a great many other people.

I think that is the big problem, you assume null and "" are the same whereas
I say they are inherently different.
So the question becomes are any of these methods really any better than
the
other and why: value == "", value == String.Empty, value.Length == 0.

I would argue value == "" or value == String.Empty simply because they say
what they are doing. Comparing length, while fairly clear, doesn't *say* you
are looking for an empty string as directly as the other two. Can I deal
with either one? Yes. But that doesn't mean that anyone should go to great
lengths to try to force or strongly recommed people use the length
comparison method. And, thus, FxCop fails greatly in that regard.
 
J

Jamus

Of some interest, in the vast majority of my code your method would
break me
pretty badly. I draw a distinction between blank, null, and " " in
almost
every circumstance. In compilers the three can be close to equal, but
in
data based apps the three are as different as each message on this
board.
Your methodology wouldn't work for me or a great many other people. <<

Up to this point I had assumed this discussion was largely one of
taste..

As I understand it, null represents no string object, which of course
is very different than a string object with no characters in it.

But aren't blank (String.Empty) and "" the same thing? An instance of
String which has no characters within it?

And for my two cents, I tend to use if(str==null||str=="") to test for
null.. I've never heard of FxCop.

Jamus
 
D

Daniel O'Connell [C# MVP]

Jamus said:
break me
pretty badly. I draw a distinction between blank, null, and " " in
almost
every circumstance. In compilers the three can be close to equal, but
in
data based apps the three are as different as each message on this
board.
Your methodology wouldn't work for me or a great many other people. <<

Up to this point I had assumed this discussion was largely one of
taste..

As I understand it, null represents no string object, which of course
is very different than a string object with no characters in it.

But aren't blank (String.Empty) and "" the same thing? An instance of
String which has no characters within it?

Yes, String.Empty and "" are the same. In my message up there I meant "" and
" ", which is a string consisting of one space, ;). I forgot how hard that
can be to see on these boards
 
Joined
Apr 18, 2006
Messages
1
Reaction score
0
I hate to point it out guys, but you're crusing for a bruising if you do it this way:
" (value == null) || (value.Length == 0) "

If the value actually IS null, value.Length will throw a NullReferenceException, so I doubt very much that is the reccomendation. Perhaps separately it is, (as in checking for string.Empty, but not at the same time as checking for null) but together no dice. You can't call a method on, or read the property of (Not even Length) of a null reference type.

Othen than that, right, string.IsNullOrEmpty(). But, I can't help but wonder, at what point does this static method of string become a bottleneck for being static... is it so fast that we'll never run into that? even if we are using say a custom xml parser, as one has alluded to here in the thread, and have several threads in the same process using that custom parser, each of which repeatedly calls string.IsNullOrEmpty() tens of thousands of times at a clip... at some point, one will be waiting in line to access the, albiet, small piece of code that in locked therein...

I always wondered the samething about DBNull.Value; Why is it that these static methods never hold up the works? or do they and they just provide such a benefit that nobody notices?

--dave dolan
 

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