Tuesday, May 31, 2011

Trial and Error–WCF Services Part 1

Decided a while ago that I would teach myself WCF (Windows Communication Framework) services.  Saw the book,  Programming WCF Services by Juval Lowy (ISBN 978-0-596-80548-7), at one of the local bookstores and decided to pick it up.  While the book is a good read, after the first chapter I was like “going to need to take notes to figure this out.”  Well, instead of doing that, I figured I’d start on a project I’ve been working on (ExpressRecipe) – the hard way – via trial and error.  Hopefully my pain will help someone else out there…
I wanted to start out with something simple first – being able to get a host running and then get the description (also known as the WSDL) of the service through a web browser.  To make things simple, I started out with a console app for the host in VS 2010.  I created a separate project under the same solution to hold the WCF service itself.
First minor sticking point – the WCF reference is not automatically included so that must be included if you’re expecting to use either the host or any of the service attributes.  So, be sure to add System.ServiceModel to all the projects that will be using WCF features.  Be sure to include the using statement for that reference as well…
My first task was to create a simple interface that will be the contract for the service.  I started out with a “user” contract that allows the client to create a new user with a first name, last name, username, and password as simple strings.  So, the interface looks like:
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.ServiceModel;
  6.  
  7. namespace ExpressRecipeWCFLibrary
  8. {
  9.     [ServiceContract]
  10.     public interface IExpressRecipeUserContract
  11.     {
  12.         [OperationContract]
  13.         void AddUser(string firstName, string lastName, string username, string password);
  14.     }
  15. }
First things you’ll notice that’s difference than a normal interface are the ServiceContract and OperationContract attributes.  In their simple forms, the service contract is placed on the interface itself.  The operation contract is placed on all the methods you want the host to expose to the client.  Only one method here so the operation contract is specified only once.  One thing of note – according to the book and the code they showed for the attributes, the attributes shown here are not inheritable – so they’ll need to be reapplied if this interface is subclassed [subinterfaced?]…they will be applied to a class that implements them though.
Ok, interface is pretty simple…next – the implementation of the interface.
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace ExpressRecipeWCFLibrary
  7. {
  8.     public class UserService:IExpressRecipeUserContract
  9.     {
  10.         #region IExpressRecipeUserContract Members
  11.  
  12.         public void AddUser(string firstName, string lastName, string username, string password)
  13.         {
  14.             System.Console.WriteLine(String.Format("{0} {1} {2} {3}", firstName, lastName, username, password));
  15.         }
  16.  
  17.         #endregion
  18.     }
  19. }
Well, actually, nothing surprising here at all – simple implementation of a normal interface…not even a mention of the System.ServiceModel reference in the usings.  Well, that’s nice and fairly easy to do…just add the ServiceContract and OperationsContract to the interface and everything else is “business as usual.”  [note that interfaces are used here – while it is recommended to use an interface and add the attributes to that, nothing prevents you from adding them to the class itself – but, the design principle applies – “program to an interface, not an implementation” so try to use an interface if at all possible].
The operations I wanted exposed as a service are done so now it’s time for the host.
In the console Program.cs file, I created a new ServiceHost and passed it the type of my UserService class (notice not the interface but the class itself).  I also decided, for debugging purposes, to attach event handlers to each of the events raised by the host.  So, the code looks something like this…
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.ServiceModel;
  6. using ExpressRecipeWCFLibrary;
  7.  
  8. namespace ExpressRecipeWCFServices
  9. {
  10.     class Program
  11.     {
  12.         static void Main(string[] args)
  13.         {
  14.             ServiceHost host=new ServiceHost(typeof(UserService));
  15.             host.Closed += new EventHandler(host_Closed);
  16.             host.Closing += new EventHandler(host_Closing);
  17.             host.Faulted += new EventHandler(host_Faulted);
  18.             host.Opened += new EventHandler(host_Opened);
  19.             host.Opening += new EventHandler(host_Opening);
  20.             host.UnknownMessageReceived += new EventHandler<UnknownMessageReceivedEventArgs>(host_UnknownMessageReceived);
  21.  
  22.             host.Open();
  23.             System.Console.WriteLine("User service started");
  24.  
  25.             System.Console.WriteLine("Press <enter> to close");
  26.             System.Console.ReadLine();
  27.             host.Close();
  28.         }
  29.  
  30.         static void host_UnknownMessageReceived(object sender, UnknownMessageReceivedEventArgs e)
  31.         {
  32.             System.Console.WriteLine("Host unknown message");
  33.         }
  34.  
  35.         static void host_Opening(object sender, EventArgs e)
  36.         {
  37.             System.Console.WriteLine("Host opening");
  38.         }
  39.  
  40.         static void host_Opened(object sender, EventArgs e)
  41.         {
  42.             System.Console.WriteLine("Host opened");
  43.         }
  44.  
  45.         static void host_Faulted(object sender, EventArgs e)
  46.         {
  47.             System.Console.WriteLine("Host faulted");
  48.         }
  49.  
  50.         static void host_Closing(object sender, EventArgs e)
  51.         {
  52.             System.Console.WriteLine("Host closing");
  53.         }
  54.  
  55.         static void host_Closed(object sender, EventArgs e)
  56.         {
  57.             System.Console.WriteLine("Host closed");
  58.         }
  59.     }
  60. }
Don’t worry, really not much code – most of it is writing to the console, mainly for the event handlers.  Ok, pretty normal code…guess we have the host so let’s run it.
Um…whoops – exception.  It runs the “host opening” event, then complains with:
“An unhandled exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll
Additional information: Service 'ExpressRecipeWCFLibrary.UserService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.”
Man, you mean VS 2010 doesn’t create a default endpoint?  And not even an App.Config file.  Oh well.  Yep, must add an App.Config file.  [this can be found in add new item under the project menu – application configuration file].  For simplicity sake, I left the name as the default…
Ok, so, now to reference the book, what needs to be in this config file?  Well, need an endpoint for the service, that part is obvious from the exception.  Need to add the service to the confile file as well…so something like:
Code Snippet
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3.   <system.serviceModel>
  4.     <services>
  5.       <service name="ExpressRecipeWCFLibrary.UserService">
  6.         <endpoint address="http://localhost:8000/UserService/" binding="wsHttpBinding" contract="ExpressRecipeWCFLibrary.IExpressRecipeUserContract"/>
  7.       </service>
  8.     </services>
  9.   </system.serviceModel>
  10. </configuration>
Ok, not obvious but it works…have to add the service class to the services list with full namespace (required to be full? – don’t know).  Then to specify the endpoint - an endpoint is the combination of address, binding, and contract so all of that is specified.  I wanted http and decided to use the web service binding (instead of basic binding, which would be the default for an HTTP address) so that I could access this service via non-WCF clients [i.e. Java].  The contract is the interface for the service with namespace specified (again – required – not sure).
So, does it work this time?  Well, let’s see – Ctrl-F5. 
image
Hmm, yep…ok, let’s try to get to the WSDL of the service.  In the browser: http://localhost:8000/UserService/ – um, nope – “The webpage cannot be found.”  Ok, well, let’s try http://localhost:8000/ – nope – still “The webpage cannot be found.”
Now what…well, according to the book, page 39, Metadata Exchange – “by default, the service will not publish its metadata.”  Well, further reading (after the very discouraging “publishing your service’s metadata involves significant effort”) we find that we can do this in a couple ways.  I chose one that seemed the easiest to me – enabling the metadata behavior (httpGetEnabled) on the endpoint.
So, going off the example in the book, my App.Config now looks like:
Code Snippet
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3.   <system.serviceModel>
  4.     <services>
  5.         <service name="ExpressRecipeWCFLibrary.UserService"behaviorConfiguration="MEXGET">
  6.         <endpoint address="http://localhost:8000/UserService/" binding="wsHttpBinding" contract="ExpressRecipeWCFLibrary.IExpressRecipeUserContract"/>
  7.       </service>
  8.     </services>
  9.     <behaviors>
  10.       <serviceBehaviors>
  11.         <behavior name="MEXGET">
  12.           <serviceMetadata httpGetEnabled="true"/>
  13.         </behavior>
  14.       </serviceBehaviors>
  15.     </behaviors>
  16.   </system.serviceModel>
  17. </configuration>
Does it run?  Nope.  It actually stopped after the host faulted event was called and gave this exception:
“The HttpGetEnabled property of ServiceMetadataBehavior is set to true and the HttpGetUrl property is a relative address, but there is no http base address.  Either supply an http base address or set HttpGetUrl to an absolute address.”
Ok, so now what?  Looking at the book’s example a bit more closely it shows the base address off of the host element of the service…and no endpoint element.  Ok, so, I replaced it with:
Code Snippet
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3.   <system.serviceModel>
  4.     <services>
  5.       <service name="ExpressRecipeWCFLibrary.UserService" behaviorConfiguration="MEXGET">
  6.         <host>
  7.           <baseAddresses>
  8.             <add baseAddress="http://localhost:8000/UserService/"/>
  9.           </baseAddresses>
  10.         </host>
  11.         <!--<endpoint address="UserService/" binding="wsHttpBinding" contract="ExpressRecipeWCFLibrary.IExpressRecipeUserContract"/>-->
  12.       </service>
  13.     </services>
  14.     <behaviors>
  15.       <serviceBehaviors>
  16.         <behavior name="MEXGET">
  17.           <serviceMetadata httpGetEnabled="true"/>
  18.         </behavior>
  19.       </serviceBehaviors>
  20.     </behaviors>
  21.   </system.serviceModel>
  22. </configuration>
I list my binding by doing this, something I’ll get back at a later time…and the contract is now gone as well.  Well, will this even work?
image
How’d that happen?  Ok, let’s see if we can access the WSDL in the browser by going to the base address specified (http://localhost:8000/UserService/).
image
Oh, cool…appears to be working…will try to get the binding back at a later time and create a client to call the AddUser method.

Tuesday, May 24, 2011

Dynamics in .Net 4.0

One of the new features of .Net 4.0 is the concept of a dynamic type.  In general terms, it allows the programmer to perform “late binding” at run time.  So, what’s so special about that – the object type allows “late binding”.  Well, does it?  What if you don’t know what type the object is but you do know it will support a method or operation?  Yes, you can always use “typeof”, “is”, or “instanceof” operators to test that it is a specific type or inherits from a specific type – but what if the method or operator doesn’t have a common inheritance tree – such as most of the operators (+, –, etc) or what if there are many possibilities/combinations.  The dynamic type solves a lot of the type checking and casting that would be required in previous versions of .Net.

For example, let’s say you’re wanting to do addition on two objects.  Let’s assume that both these objects support +.  The general concept of late binding says that you “should” be able to do something like:

  1: object value1=1;
  2: object value2=2;
  3: object value3=value1+value2;

The above code will give you “Error 1 Operator '+' cannot be applied to operands of type 'object' and 'object'”.  The solution is to cast these as ints such as:

  1: object value1 = 1;
  2: object value2 = 2;
  3: object value3 = (int)value1 + (int)value2;

Ok, so that works – no compile error…but, what if value1 was a double, not an int…or, what if value1 or value2 could be either int or double…then you’re stuck with some nasty code like:

  1: object value1 = 1;
  2: object value2 = 2;
  3: object value3;
  4: if (value1 is int)
  5: {
  6:     if (value2 is int)
  7:     {
  8:         value3 = (int)value1 + (int)value2;
  9:     }
 10:     else if (value2 is double)
 11:     {
 12:         value3 = (int)value1 + (double)value2;
 13:     }
 14: }
 15: else if (value1 is double)
 16: {
 17:     if (value2 is int)
 18:     {
 19:         value3 = (double)value1 + (int)value2;
 20:     }
 21:     else if (value2 is double)
 22:     {
 23:         value3 = (double)value1 + (int)value2;
 24:     }
 25: }
 26: 

Add another type that both could be and it increases the code more…not nice at all.


Around .Net 3.5, Microsoft added the var type.  The var type infers a type at design time.  This is nice in our example case and actually works so:

  1: var value1 = 1;
  2: var value2 = 2;
  3: var value3 = value1 + value2;

Actually works – it compiles and we get 3.  If we change a or b to be a double, value3 gets a double result (double + int=double) as expected if we had explicitly typed the variables.  Great, problem solved – right?  Wrong…  Let’s add another monkey wrench into this…


Suppose we want a function that converts a string to the “best” type that that string represents.  So, a string value of “2.4” would return a double 2.4, a “12/25/2011” would return a DateTime of 12/25/2011, etc.  Then we’d like to take the result of that and add it to another result from that same function.  This would work with object, but we’d be back in the exact same situation as before – testing with “is” and casting.  What about var?  (the GetBestType function is a prototype only – it works but it needs more error checking, validation, etc).

  1: var value1 = GetBestType("1.2");
  2: var value2 = GetBestType("2");
  3: var value3 = value1 + value2;
  4: 
  5: public var GetBestType(string value)
  6: {
  7:     double doubleResult;
  8:     if (double.TryParse(value, out doubleResult))
  9:     {
 10:         return doubleResult;
 11:     }
 12: 
 13:     int intResult;
 14:     if (int.TryParse(value, out intResult))
 15:     {
 16:         return intResult;
 17:     }
 18:     
 19:     DateTime dateResult;
 20:     if (DateTime.TryParse(value, out dateResult))
 21:     {
 22:         return dateResult;
 23:     }
 24: 
 25:     return value;
 26: }
 27: 
Well, first thing with that code – won’t even compile.  Seems the var keyword is only for local variables.  Well, back to old reliable object, right?  If we were using .Net 3.5 or before, yes…this is where dynamic comes in for .Net 4.0.

The dynamic type is determined at run time…so, fixing our code to use dynamic, we can do this:

  1: var value1 = GetBestType("1.2");
  2: var value2 = GetBestType("2");
  3: var value3 = value1 + value2;
  4: 
  5: public dynamic GetBestType(string value)
  6: {
  7:     double doubleResult;
  8:     if (double.TryParse(value, out doubleResult))
  9:     {
 10:         return doubleResult;
 11:     }
 12: 
 13:     int intResult;
 14:     if (int.TryParse(value, out intResult))
 15:     {
 16:         return intResult;
 17:     }
 18:     
 19:     DateTime dateResult;
 20:     if (DateTime.TryParse(value, out dateResult))
 21:     {
 22:         return dateResult;
 23:     }
 24: 
 25:     return value;
 26: }

Yes, we’re returning either a double, an int, a DateTime, or a string from one function and the code works as expected.


While the above code works, and minimizes code vs late binding type checking, both the dynamic and var keywords should be used sparingly in favor of code readability.  Technically, while you could create every variable as var or dynamic, it would greatly reduce readability…so, use sparingly when needed (i.e. when you’d be tempted to use object and type checking).  It is much better than using object, but it should never replace a explicitly typed variable, if you have the choice.

Static Constructors in .Net

Suppose you’re creating a class in .Net and you want certain operations only done once, at the very first time your class is used.  First thoughts?  A flag to test to see if it’s the first time into the class – suppose your class has 100 static and non-static functions – that code to do the check must be in each of those.  What a pain…  Next idea? (And, no, you’re not allowed to cheat and use a Singleton)  What?  No more ideas…

The solution – use a static constructor.  Static constructors are called only once, when the class is first used, either through static members or object members (i.e. non-statics).

Static constructors are really not much different from regular constructors in definition except they can’t have access modifiers (i.e. public, private, protected, etc).  They are called before the normal constructor.  But, being static, they can only access static members of that class.  Here’re the other rules about static constructors from Microsoft (http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=VS.100).aspx):

  • A static constructor does not take access modifiers or have parameters.

  • A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.

  • A static constructor cannot be called directly.

  • The user has no control on when the static constructor is executed in the program.

  • A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.

  • Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.

  • If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.

Here’s a quick example class that creates a Singleton using the static constructor.

  1: public class StaticSingleton
  2:     {
  3:         static StaticSingleton staticSingleton;
  4: 
  5:         private StaticSingleton ()
  6:         {
  7:         }
  8: 
  9:         static StaticSingleton()
 10:         {
 11:             staticSingleton = new StaticSingleton();
 12:         }
 13: 
 14:         public static StaticSingleton GetInstance()
 15:         {
 16:             return staticSingleton;
 17:         }
 18:     }

Here’s the non-static constructor version for comparison:

  1:     public class Singleton
  2:     {
  3:         static Singleton singleton;
  4: 
  5:         private Singleton()
  6:         {
  7:         }
  8: 
  9:         public static Singleton GetInstance()
 10:         {
 11:             if (singleton == null)
 12:             {
 13:                 singleton = new Singleton();
 14:             }
 15:             return singleton;
 16:         }
 17:     }

Friday, May 20, 2011

True Random Numbers in SQL

Co-worker stumbled across this one and thought it was a good way to generate random numbers in SQL Server.

Often, random numbers are driven off of the uniqueness of the ticks/millisecond part of the current date/time but that code may run so quickly that you’re not guaranteed a different value between each random request. 

The solution – use GUIDs as the source for the random function as GUIDs are “guaranteed” to be unique.  Of course, some casting is involved as the random function does not take a string.  So, the solution is to cast the GUID as a var binary, then convert that to an int, then pass the absolute value of that that into rand (since it only allows positive ints).  Here’s the general code:

  1: RAND(ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)))

As normal, rand returns a float/double between 0 and 1.

Monday, May 16, 2011

String Equality and Performance in C#

Strings in .Net are one of the more used primitives but are also the most problematic performance wise.  In college and while learning through books, etc. , we’re told that to concatenate two strings, use the + operator.  The + operator seems to become habit fairly quickly and sticks with us, and we wonder why our programs are taking seconds between operations and eating megs of memory.  It’s only after running a performance analyzer we realize the culprit – the old standby + operator which is taking seconds to concat two strings.  We learn through that that we can increase performance and reduce memory usage by using StringBuilder and its Append method instead and bring seconds down to milliseconds and drop megs off the memory footprint.  While this may not be the fastest method out there, it sure beats the + operator that we get into the habit of using.
We’re also told to use the == operator (or .equals in Java) for string equality.  Is == the best operator to use when doing string equality operations?  And, is there a fast case-insensitive way to do string equality?
As usual, there’s more than one way to do a task in .Net and string equality is no exception.  I counted at least 24 different ways using the .Net built-in methods.  A lot of the different ways come from doing string comparisons and doing the comparisons based on culture (Windows-installed, current, etc) or on doing a binary comparison…speed is also determined based on whether you’re doing a culture-specific comparison or doing a simple binary comparison (i.e. via ASCII/Unicode-table).  Sting equality is not exactly the same as string comparisons so I’m ignoring culture in this post, with the exception of which performs the best given the circumstances.
Grouping the equality operations together without their culture options, there are 6.  The == operator, .equals, .CompareTo, the static methods string.equals, string.Compare, and string.CompareOrdinal.
Since, in general, string equality operations are very fast when done as a single operation, I’ve ran tests based on 6,250,000 (2,5002) string equality tests.  For these tests, I have a routine to create 2,500 randomly-generated strings.  I tested with string lengths between 1 and 1k (1024).
Ok, so the answer to which is faster – well, guess what, it depends.  [nothing is ever as easy as it seems, is it?].  The answer is different depending on if you’re dealing with same-length strings vs different length strings, and on whether you’re wanting to ignore case or not.  There are sure to be other reasons for the speed difference as well but here’re my results.  I’ll do the comparison based on different vs same length strings – just use the best function listed for whether to ignore the case or not.

DIFFERENT Length Strings

.equals and string.equals seem to be pretty much tied for 1st and 2nd place with time around .09 seconds (the .Net timer object I was using for the time calculation has an accuracy to .001 seconds).  Both of these are using ordinal ignore case comparison.
Here’s the other results for comparison:
.equals (ordinal ignore case) .097
string.equals (ordinal ignore case) .098
.equals (ordinal) .120
.equals .121
string.equals (ordinal) .127
== .135
string.CompareOrdinal .239
.equals (invariant culture) .627
.equals (invariant ignore case) .635
string.compare (ignore case) .658
.equals (current culture ignore case) .659
string.compare .660
string.equals (current culture ignore case) .673
string.equals (invariant ignore case) .676
string.equals (current culture) .682
.CompareTo .684
.equals (current culture) .689
== (w/ ToLowerInvariant inline) 24.153 (yes, seconds)
== (w/ ToUpper inline) 25.071
== (w/ ToUpper external) 25.029
== (w/ ToLower inline) 25.504
== (w/ ToLower external) 25.730

 

SAME Length Strings

For same length strings, things are slightly different – string.equals (ordinal) and .equals (ordinal) are at the top, not the ordinal ignore case.  Here’s the rundown for same length strings.  I’ve omitted the ToLower/ToUpper results as they were just horrible in performance.
string.Equals (ordinal) .124
.equals (ordinal) .128
string.compareOrdinal .132
.equals .133
== .146
.equals (ordinal ignore case) .213
string.Equals (ordinal ignore case) .230
string.Equals (invariant culture ignore case) .577
string.Equals (invariant culture) .578
.equals (invariant culture ignore case) .611
string.Equals (current culture ignore case) .620
.equals (current culture) .622
string.Equals (current culture) .630
.CompareTo .634
.equals (invariant culture) .636
string.compare (ignore case) .638
string.compare .686

 

Code

Ok, so you don’t want to look up how to do an ordinal ignore case equality against two strings…well, here’s the code snipets.  Variables str1 and str2 are strings.

==

This one is easy – not much explanation needed.
1: if (str1 == str2)


.Equals


String object method – similar to Java’s equals method.
1: if (str1.Equals(str2))


string.Compare


One of the static string compare functions.  Returns 0 if strings are equal.  Several options available.
1: if (string.Compare(str1, str2) == 0)


string.CompareOrdinal


Another static string compare function – compares using binary comparison instead of text so it uses the ASCII/Unicode table for its comparison.
1: if (string.CompareOrdinal(str1, str2) == 0)


string.Compare (ignore case)


An overload to string.Compare that ignores case of the characters.
1: if (string.Compare(str1, str2,true) == 0)


string.Equals, .Equals (current culture)


Compares strings using the current machine/user’s culture).  Overload of the equals method.
1: if (string.Equals(str1, str2,StringComparison.CurrentCulture))
1: if (str1.Equals(str2,StringComparison.CurrentCulture))
string.Equals, .Equals (current culture ignore case)
Same as equals current culture – just ignores case
1: if (string.Equals(str1, str2, StringComparison.CurrentCultureIgnoreCase))
1: if (str1.Equals(str2, StringComparison.CurrentCultureIgnoreCase))


string.Equals, .Equals (invariant culture)


Compares based on the installed Windows culture.
1: if (string.Equals(str1, str2, StringComparison.InvariantCulture))
1: if (str1.Equals(str2, StringComparison.InvariantCulture))


string.Equals, .Equals (invariant culture ignore case)


Ignores case but compares on the currently installed Windows culture.
1: if (string.Equals(str1, str2, StringComparison.InvariantCultureIgnoreCase))
1: if (str1.Equals(str2, StringComparison.InvariantCultureIgnoreCase))


string.Equals, .Equals (ordinal)


Performs binary (ASCII/Unicode) comparison.
1: if (string.Equals(str1, str2, StringComparison.Ordinal))
1: if (str1.Equals(str2, StringComparison.Ordinal))


string.Equals, .Equals (ordinal ignore case)


Binary comparison but ignores case.
1: if (string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase))
1: if (str1.Equals(str2, StringComparison.OrdinalIgnoreCase))


.CompareTo


String object compare to method – similar to string compare method except no overloads other than comparing strings to objects.
1: if (str1.CompareTo(str2) == 0)


== (w/ ToLower), == (w/ ToUpper), == (ToLowerInvariant)


Sadly, this is how I’ve done case insensitive searches for years (even in .Net) thanks for my many years programming in BASIC and QuickBasic – neither of which had the many ways to do string equality that .Net has.  This is also, sadly, one of the slowest ways to do string case insensitive equality.  The true cost here is the ToLower case conversion, which is just slow.  This, just like the + operator for strings, is one of those “don’t do these” features of strings.  If you’re needing to do case insensitive equality, use something else…
1: if (str1.ToLower()==str2.ToLower())
1: if (str1.ToUpper() == str2.ToUpper())
1: if (str1.ToLowerInvariant() == str2.ToLowerInvariant())


== (w/ ToLower external), == (w/ ToUpper external)


Essentially the only difference here is ToLower is pulled outside of the equality – so essentially the case conversion is done elsewhere…still takes a LOT of time to do the conversion on top of the equality.
1: string a = str1.ToUpper();
2: string b = str2.ToUpper();
3: if (a == b)


Conclusion


Well, since most strings in .Net (and Java) are different length strings, it’s best to use .equals over the == operator.  If the program does not care about case nor culture comparisons, adding in the case insensitive ordinal comparison also helps as well.  Of course, the performance is minor in comparison to the + operator, but, if you’re dealing with millions (or billions) of string equalities, every millisecond gained helps.  Definitely avoid use of ToLower or ToUpper to do comparisons/equality.

Monday, May 9, 2011

Easy Separated Lists in .Net


Found a simple way of doing a separated list, similar to PHP's implode function. The code expects the variable "Values" to be of an IEnumerable type, which includes arrays, lists, etc.  Very useful for doing comma delimited lists.



Instead of doing:

string commaList = "";



foreach (string value in Values)

{

    commaList = commaList + value;

    commaList = commaList + ", ";

}

commaList = commaList.Substring(0, commaList .Length - 2);



It's easier (and faster) to do (.Net 4.0):

string commaList=string.Join(", ", Values);



.Net 3/3.5:

string commaList=string.Join(", ", Values.ToArray());



.Net 2.0:

string commaList=string.Join(", ",new List<string>(Values).ToArray());



Of course the join function allows any separator to be used, not just ", ".

And, according to this post, string.Join is faster than StringBuilder in this particular case.