Posts
201
Comments
1111
Trackbacks
51
December 2005 Entries
Property Manager AddIn

I just installed this VS2005 add- in and it does everything I WISH the VS2005 IDE “encapsulate field” function would have done:

http://www.csharper.net/blog/property_manager_addin_for_visual_studio_2005.aspx

Posted On Monday, December 12, 2005 6:24 AM | Comments (0)
Not all string comparisons created equal

Not all string comparisons will perform the same but I was interested in seeing what exactly the differences were. Regardless of whether I was just performing 1 string comparison or 1 million, using the instance Equals() method was BY FAR the fastest. Of course the danger there is it will fail if the first string is null. Using == will always work regardless of nulls and for a million comparisons was almost as fast as Equals() and WAY faster than any other method (although it should be noted that using == is identical to using the static String.Equals() method). However, for 1 comparison it was by far the slowest. Note, for case-insensitive comparisons it is much faster to use the Compare() method with the case insensitive switch. Here are results below:

1 COMPARISON:
first == second                                                 : 0.00021175875704873100
first.Equals(second)                                          : 0.00000866031856004045
(first.CompareTo(second) == -1)                     : 0.00005531429273832290
(string.Compare(first, second) == -1)                : 0.00001396825574200070
string.Compare(first, second, true) == -1          : 0.00001145396970844060
first.ToLower() == second.ToLower()              : 0.00002458413010592130

1000000 COMPARISONS:
first == second                                                 : 0.05631637540525400000
first.Equals(second)                                          : 0.03321874707539650000
(first.CompareTo(second) == -1)                     : 0.28999719238059600000
(string.Compare(first, second) == -1)                : 0.29059363690077900000
string.Compare(first, second, true) == -1          : 0.30738375966777900000
first.ToLower() == second.ToLower()              : 0.77666714624344700000

Incidentally, a look at the instance Equals() method in Reflector:
[MethodImpl(MethodImplOptions.InternalCall)]
public extern bool Equals(string value);

 

Doing a million string comparisons in a loop might not be your common every day programming task and the timing difference will obviously not be perceptible to a human.  But let's say you have a web page that does a single string comparison - if that page is accessed in a high volume environment (by thousands of browsers at once), then every little performance enhancement you can make is quite important.

Posted On Sunday, December 11, 2005 10:03 AM | Comments (0)
Limitations of Generics Polymorphism

With the advent of .NET 2.0, Generics is undoubtedly the single most important language enhancement.  However, to use generics to the full potential, developers should understand both the capabilities and limitations of generics as they relate specifically to polymorphism.  In short, while generics do support some polymorphic behavior, the use of Interfaces should still be the preferred polymorphic mechanism in many cases.

 

First, an example of polymorphic capabilities,

abstract class Person

{

    public string FirstName;

    public string LastName;

    public void Speak();

}

class Fireman : Person

{

    public int NumFiresExtinguished;

}

class Policeman : Person

{

    public int NumArrestsMade;

}

 

Using System.Collections.Generics.List<>, one could consume like this:

List<Person> list = new List<Person>();

list.Add(new Fireman());

list.Add(new Policeman());

Since both Fireman and Policeman inherit from Person, this compiles just fine.

 

Futher, with constraints we can define our own generic sub-classes:

class PersonAction where T : Person

{

    public void DoAction(T item);

}

 

Like the example above, we can consume like this:

PersonAction<Person> personAction = new PersonAction<Person>();

personAction.DoAction(new Fireman());

personAction.DoAction(new Policeman());

 

PersonAction<Fireman> fireAction = new PersonAction<Fireman>();

fireAction.DoAction(new Fireman());

//fireAction.DoAction(new Policeman()); <--Does not compile which is good

 

So far, everything is as we expect.  However, if we try to push generic polymorphic behavior one step further, this is where things gets interesting.

List<PersonAction<Person>> personActionList = new List<PersonAction<Person>>();

//personActionList.Add(new PersonAction()); <--Does not compile

//personActionList.Add(new PersonAction()); <--Does not compile

 

One would think that these two previous statements would be legal.  After all, we specified that the PersonAction must be and PersonAction certainly seems to satisfy this at first glance.  However, the compiler does not allow this because when we use generics in this way, the compiler is expecting the exact type – Person.

 

The good news is that this situation is easily rectified by using Interfaces.

interface IAction

{

    void DoAction(Person item);

}

And we’ll change PersonAction to:

class PersonAction : IAction where T : Person

{

    public void DoAction(T item);

    public void DoAction(Person item)

    {  this.DoAction((T)item); }

}

Now we can simply do this for polymorphic behavior with generic classes:

List<IAction> personActionList2 = new List<IAction>();

personActionList2.Add(new PersonAction<Fireman>());

personActionList2.Add(new PersonAction<Policeman>());

 

While there is no doubt that generics is one of the most important language enhancements we’ve seen in a while, there are many situation where traditional OOP with Interfaces should be the preferred implementation to support generics.

Posted On Monday, December 5, 2005 6:01 PM | Comments (6)

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

Tag Cloud