 |
|
 |
You should keep in mind that the .Net compiler and VM are tricky beasts, not to mention the JIT. What you write is not always what ends up as IL, because the compiler takes a lot of steps to remove things like unused variables, and unused code blocks. Case in point, if you write an if statement that is empty, in certain situations compiler won't do the comparisons. It will just do the bare minimum to insure any methods that would have been called are called. So, "if (providedString.Length == 0) {}", will be turned into "int v1 = providedString.Length". As far as you know the comparison happened, because .Length was called, but if the if statement was empty it has no reason to generate any jump statements and thus can reduce branching by optimizing out the compare. So you should make sure you do something like set a dummy variable, AND make sure that you do something besides assign a value to that variable, like write it out at the end of the test.
In any event, your numbers are correct, though you missed testing several other cases.
StrTest.exe ""
00:00:13.4399774 : if (providedString == "")
00:00:45.2679716 : if (providedString == String.Empty)
00:00:03.7695695 : if (providedString.Length == 0)
00:00:07.6226158 : if (String.IsNullOrEmpty(providedString))
00:00:05.6808094 : if (providedString == null || providedString.Length == 0)
00:00:46.1933111 : if (String.CompareOrdinal(providedString, String.Empty) == 0)
00:00:13.2321548 : Interned: if (intProvidedString == intEmpty)
00:00:13.1926274 : Interned: if (intProvidedString == intStringDotEmpty)
00:00:03.7688974 : Unsafe: if (ptrProvidedString == ptrEmpty)
StrTest.exe abc
00:00:35.5452142 : if (providedString == "")
00:00:35.5312962 : if (providedString == String.Empty)
00:00:03.8246581 : if (providedString.Length == 0)
00:00:07.7108658 : if (String.IsNullOrEmpty(providedString))
00:00:05.7747759 : if (providedString == null || providedString.Length == 0)
00:00:49.0967074 : if (String.CompareOrdinal(providedString, String.Empty) == 0)
00:00:35.3541753 : Interned: if (intProvidedString == intEmpty)
00:00:35.4164999 : Interned: if (intProvidedString == intStringDotEmpty)
00:00:03.8559366 : Unsafe: if (ptrProvidedString == ptrEmpty)
If you intern the strings, and perform a comparison of the fixed string pointers you can match the speed of the length test.
As for why it took longer when you compared "abc" vs "", it was probably just due to additional branching that occurred because of the difference in the strings, or maybe you had another process taking up cycles. But that's just my guess. Honestly it could have happened for any number of reasons.
Personally I use String.NullOrEmpty() just because I find it much easier to read, and the only additional overhead I'm paying is the method call, as compared to writing if (str == null || str == "") everywhere.
Though, this debate is fairly moot, because if you have to start optimizing your string compares, odds are .Net was not the right choice for the project or you're just a really terrible programmer.
|
|
|
|
 |
|
 |
ZeroDegrez wrote: So you should make sure you do something like set a dummy variable, AND make sure that you do something besides assign a value to that variable, like write it out at the end of the test.
Yes, I did that. I've run into that before, and smacked my head suitably hard.
ZeroDegrez wrote: this debate is fairly moot
I agree, and now when someone knee-jerkedly says to always test .Length we can point them here.
|
|
|
|
 |
|
 |
I usually use string.IsNullOrEmpty() or string.length > 0.
|
|
|
|
 |
|
|
 |
|
 |
Looks like another .NET myth...
I always preferred if (somestring == "")
Semantically "" and string.Empty work better than something.Length == 0 as they reflect the nature of you comparison. You see, you are not really interested in the length of the string, but rather in the string being empty.
"" arguebly better than string.Empty as it is less verbose.
Also keep in mind that if you even have "" 100 times in your code compiler creates static reference to the single string entry embedded in your assembly. Thus there is no any penalty for using "". And because of this "" is not different to localstaticemptystring but again "" is less verbose.
So I guess there is no real reason why "" should be avoided.
However semantics is a tricky topic and plenty of people would disagree with me.
|
|
|
|
 |
|
 |
Yes, if (somestring == "") is more expressive.
And given that the difference in performance isn't all that bad, I won't feel too bad continuing to write it that way.
I really don't see any purpose of String.Empty.
|
|
|
|
 |
|
 |
The only one approach that might be potentially better (more readable and not verbose) than somestring == "" is IsNullOrEmpty(). However MS guys made a strange decision to implement it as static, so it is not as expressive as it can be. The fiollowing is the fragment of MSDN code sample:
if (string.IsNullOrEmpty(s) == true) return "is null or empty" |
Though if one is really keen to have as fast as possible and still readable test on emptiness Extension Methods can help:
public static class Extensions { public static bool IsNullOrEmpty(this string s) { return string.IsNullOrEmpty(s); } }
....
if (s.IsNullOrEmpty()) return "is null or empty" |
|
|
|
|
 |
|
 |
Oleg Shilo wrote: if (s.IsNullOrEmpty())
return "is null or empty"
Calling a method on an instance that might be null ??
C'mon...
Regards
Thomas
www.thomas-weller.de
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. Programmer - an organism that turns coffee into software.
|
|
|
|
 |
|
 |
Indeed, Extension Methods are obfuscation. I see no reason to use them.
(I also don't like how they were implemented for C#.)
|
|
|
|
 |
|
 |
Well, we are entering very different area now...
Extension Methods one of the most contraversial topics in C#.
If you are trying to use Extension Methods to mimic some OO concepts you will be disappointed. Extension Methods completely fail to do this. The code sample above demonstrates how absurd (from OO programming point of view) this can be. Calling method on null instance without failing? Shish...
However forget about OO for a moment. Look at Extension Methods as something provided by rather language runtime than an instance of a type.
string myString = "";
....
if (myString.IsNullOrEmpty())
The code above semantically (but not OO-ly) makes perfect sense. You have a variable (myString) and you are checking if it is null or empty. And you are just reusing OO style of syntax.
By no means I am saying Extension Methods is everyone's cup of tee. Plenty of people believe that anonymous methods, lambda expressions, implicit typing are all rubbish polluting pure OO nature of C#. And, technically, they are absolutely right. Anonymous methods (or even classes) break everything we know about OO.
At the end of the day the question is: Is It Ok To Use Syntactic Sugar?
You will be surprised how many people don't care if a particular language functionality implemented on CLR or Language Compiler lever. Look at success of LINQ, which has almost everything based on syntactic sugar.
BTW, there is an indirect indication that MS may introduce Extension Properties in C# 4.0.
But of course it is up to a particular developer to decide which way to go.
|
|
|
|
 |
|
 |
I didn't mean such general things. It's much simpler:
Look at the following piece of code:
string myString;
....
if (myString.IsNullOrEmpty())
This means: you are checking a reference for null by calling a method on this instance.
Am I the only one who finds this totally wrong? Or am I missing something?
Regards
Thomas
www.thomas-weller.de
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. Programmer - an organism that turns coffee into software.
|
|
|
|
 |
|
 |
Thomas Weller wrote: Am I the only one
You are not alone.
|
|
|
|
 |
|
 |
Just tried what you said. It does not work.
string myString;
....
if (myString.IsNullOrEmpty())
The correct syntax is:
string myString;
....
if (string.IsNullOrEmpty(myString))
We never use the instance for IsNullOrEmpty
|
|
|
|
 |
|
 |
Some extension methods make it look like you are.
|
|
|
|
 |
|
 |
hey PIEBALDconsult,
I did not understand your reply.
A static method (IsNullOrEmpty) of String class is called by passing an instance of string to it.
Is this a Extention method?
We use this is our project and believe that it is the fastest to check zero lenght as well as null string
if(string.IsNullOrEmpty(instanceString))
While following code will check only zero length string. Null check will be missed
if(instanceDString.Length == 0)
|
|
|
|
 |
|
 |
Yes, that's all fine. I use string.IsNullOrEmpty when appropriate.
A static method doesn't need an instance, but an instance method does. So calling string.IsNullOrEmpty ( instanceString ) when instanceString is null works just fine. Calling instanceString.Length when instanceString is null will throw an exception.
ExtensionMethods are static methods that are used like instance methods.
If someone writes an IsNullOrEmpty entension method, it would be called as instanceString.IsNullOrEmpty(), but logically it should throw an exception if instanceString is null rather than return true.
|
|
|
|
 |
|
 |
That clears my queries .. thanks PIEBALDconsult
|
|
|
|
 |