Oct 26 2009

CompiledQuery… I wanna have yo babies!

Category: C#,LINQ,Software Development,UncategorizedWil @ 9:21 pm

A co-worker and friend of mine, Dr. Steve Morrison, came to me the other day and asked if I had used the CompiledQuery (System.Data.Linq.CompiledQuery) class with LINQ-to-SQL. I told him that I had not and he said that he read that it was a big performance gain over just straight LINQ queries. Skeptical as I usually am, I let it sit on frontal lobe’s back burner for a day or so and occasionally asked Steve if he had done any testing with it yet. Today, he still hadn’t done any testing so I curiosity killed my patient little cat and I wrote a few tests to see what kind of performance improvements this “extra step” could make.

But first, if you plan on doing any of your own tests, you need to know how to clear SQL Server’s cache before each test run. You do that by executing the following SQL commands:

DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO

I suggest putting that into a stored procedure and just calling it from LINQ-to-SQL (as I did in this test).

Now to the testing. My test database is a SQL Server 2008 database that has a decent amount of data in it; roughly 140K records in the one test table I use for this test. I am using LINQ-to-SQL (without the T4 templates) in C# for this test. All tests were run in release mode on a Quad-core PC running Windows 7 with 4GB of RAM.

And as a side note, no underscores were harmed in the making of these tests!  You have to be “in the know” to get that joke.

Test 1: Incremental record Count retrieval (from 1 record to 5000 records incrementally)
Basically, there is a loop from 1 to 5000. If the [Id] (the primary key of the table) is less than or equal to the index of the loop, I retrieve that record. As the loop progresses, the query will bring back more and more records. Eh, it’s a test… leave it at that.

Test 2: Get one record at a time… 5000 times
Again, there is a loop from 1 to 5000. If the [Id] (the primary key of the table) is equal to the index of the loop, I retrieve that record. The query will always return a single record… a different record… but a single one.

Here’s the non-compiled, normal LINQ-to-SQL:

// BaseTestClass has Logging and the Clear method... don't worry about it!
internal sealed class NonCompiledQueryTest : BaseTestClass
{
	public void Run()
	{
		ClearDatabaseCache();

		using (var dataContext = new TestDbDataContext(_connectionString))
		{
			dataContext.ObjectTrackingEnabled = false;

			Log("Starting Non-Compiled Test");
			DateTime start = DateTime.Now;
			for (int index = 0; index < 5000; index++)
			{
				var q = from r in dataContext.GetTable<MySampleTableFullOfData>()
				        where r.Id == index select r;
				q.ToList();
			}
			Log("Non-compiled: " + DateTime.Now.Subtract(start).TotalSeconds);
		}
	}
}

And here’s the Compiled LINQ-to-SQL:

internal sealed class CompiledQueryTest : BaseTestClass
{
	public void Run()
	{
		ClearDatabaseCache();

		using (var dataContext = new TestDbDataContext(_connectionString))
		{
			dataContext.ObjectTrackingEnabled = false;

			Log("Starting Compiled Test");
			DateTime start = DateTime.Now;
			for (int index = 0; index < 5000; index++)
				Compiled(dataContext, index).ToList();

			Log("Compiled: " + DateTime.Now.Subtract(start).TotalSeconds);
		}
	}

	static private readonly Func<TestDbDataContext, int, IQueryable<MySampleTableFullOfData>> Compiled =
		CompiledQuery.Compile<TestDbDataContext, int, IQueryable<MySampleTableFullOfData>>(
			(dc_, index_) =>
			from r in dc_.GetTable<MySampleTableFullOfData>()
			where r.Id == index_
			select r);
}

Results? Stop being so pushy! Here ya go:
CompiledQueryResults

Those numbers are the total number of seconds taken to run each test. I was completely blown away by the results. I honestly thought there was something wrong with the results from Test 2 so I ran that test as many different ways as I could… all produced the same exact results. That’s just awesome! Time to refactor some existing code!

The CompiledQuery improvements really shine when there are a lot of queries executing; not a single query that brings back a lot of records. In the later case, I found the compiled query to be about the same or just a smidgeon slower. With multiple queries… it just blows away normal, non-compiled, queries.

Enjoy!

Tags: , ,


Oct 22 2009

SuperStarThemes.com == Awesome!

Category: Software Development,WebWil @ 9:33 am

slide_welcomeRecently, I have been looking for some “business” WordPress themes. And after what seemed like an endless and unsatisfying journey, I finally came across a company named Super Star Themes.  Their prices are fantastic, their service is superb, and the quality of their work seems to be outstanding!

If you are looking for a new WordPress theme and don’t have the time to “roll your own”, be sure to check them out.  You won’t be disappointed!

Tags:


Oct 19 2009

Math.Round == Bankers Round

Category: C#,Software DevelopmentWil @ 3:25 pm

Today I was trudging through some old code and came across a (nasty-looking) line of code like this:

// OMG this is nasty!
price = Convert.ToDecimal(Convert.ToDouble(price.ToString("#######.##")));

I thought, “What the hell is going on here?!”. This was inside a two-case switch statement (which is also totally retarded) and the second case had this type of logic in it:

price = Math.Round(price + 0.005, 2);

So I decided to do a little testing (using the awesomeness that is LINQPad) with this curious rounding code. Running this through LINQPad produces interesting output:

void Main()
{
	12.365.ToString("#######.##").Dump();
	12.375.ToString("#######.##").Dump();
	12.385.ToString("#######.##").Dump();

	"----------------------".Dump();

	Math.Round(12.365, 2).Dump();
	Math.Round(12.375, 2).Dump();
	Math.Round(12.385, 2).Dump();
}

Output:

12.37
12.38
12.39
----------------------
12.36
12.38
12.38

The .NET Math.Round actually does not do “engineering” rounding… it does “bankers’” rounding. Here is how “bankers’” rounding works: If the next-to-last digit of the number you’re rounding is an even number, you round up. If it is an odd number, you round down. So 12.365 rounds up to 12.37… and 12.375 rounds down to 12.37. Crazy huh! Gotta love those bankers trying to hold onto their precious pennies!

The other odd-looking rounding using the ToString method actually give you “engineering” rounding… or simply “normal” rounding. What a PITA!

On a tangential thought, it appears that Math.Truncate and Math.Floor have identical results.

You’ve been warned!


Oct 13 2009

Online Whiteboard

Category: Software Development,ToolsWil @ 7:46 am

Twiddla.com is a new web-based company that provides online whiteboarding. It’s awesome and needs no other commentary from me. Just go check it out!

Tags:


Oct 12 2009

Params & Extension Methods

Category: C#,Extension MethodsWil @ 10:25 am

This morning I was working on some legacy code (code I find that has no corresponding unit tests assigned to it) and found myself wanting the C# equivalent of the SQL “NOT IN” and “IN” statements. For example,

SELECT COUNT(*) FROM
WHERE NOT IN { }

So, I wrote a simple little extension method class to do just that:

static public class Extensions
{
	static public bool IsIn(this Int32 value_, params Int32[] list_)
	{
		// LINQ is less efficient...
		// return list_.Where(v => { return v == value_;}).Count() > 0;
		// ...than this:
		foreach (var value in list_)
			if (value == value_)
				return true;

		return false;
	}
	static public bool NotIn(this Int32 value_, params Int32[] list_)
	{
		return !IsIn(value_, list_);
	}
}

Now you can write code like this:

public void Example1 (Int32 [] someList_)
{
   if (5.IsIn(someList_)
      DoSomethingSexy();
}

… or like this:

public void Example2 (Int32 value_)
{
   if (value_.NotIn(_myList))
      DoSomethingElseSexy();
}

Enjoy!


Jul 27 2009

Capability Classes & Queries

Category: C Plus Plus,C#,Philosophy,Software DevelopmentWil @ 7:41 pm

ostrich_headLast week, I had the honor and pleasure of teaching an Advanced C++ class at ExxonMobil in Houston, Texas. All of the students were brilliant and were employees in their Research division. I think I was the only one there without a PhD. In fact, several of them, had multiple doctorates or post-doctorates… which I didn’t even know existed.

But I digress. Since I hadn’t taught that class in about a decade and hadn’t used C++ professionally since circa 2003, my brain pushed a lot of my C++ knowledge out into its proverbial “garage” for later retrieval. After several days of submersion in the language and C++ labs, we finally got to some clever inheritance problems and polymorphism tricks. That brought back my long, lost memory of “Capability Classes and Capability Queries”.

While not exactly rocket science, Capability Queries can be of use in C# as well as C++. So here is what a capability class looks like… well, wait, let’s lay sound ground work first:

public class Animal { }
public class WarmBloodedAnimal : Animal { }

public class Human : WarmBloodedAnimal { }
public class Bird : WarmBloodedAnimal { }

Nothing really special there is there? Both birds and a humans are warm-blooded animals. So what?!

What if we had a collection of animals… say, just for arguments sake, a List collection. Now, you would like to only have a subset of that list… in which the resultant list is warm-blooded animals that have the ability of flight. Let’s ignore the fact that we have LINQ queries for now and just focus on the subject at hand. In some random method, we could do something like this:

public void SomeRandomMethod(IList<Animal> animals_)
{
   foreach (var animal in animals_)
      if (animal is Bird)
         (animal as Bird).Fly();
}

But, what about birds that can’t fly?! Penguins can’t fly but they’re excellent swimmers. Should we add an attribute to the Animal base class for “IsCapableOfFlight”? I think not. Why pollute the interface and thusly pollute every derived class with that attribute!?!

That brings us to Capability Classes (Interfaces in C#).

public interface CapableOfFlight
{
   public void Fly();
}
public class Eagle : Bird, CapableOfFlight { }
public class Parakeet : Bird, CapableOfFlight { }
public class Ostrich : Bird { }
public class Penguin : Bird { }

public void SomeRandomMethod(IList<Animal> animals_)
{
   foreach (var animal in animals_)
      if (animal is CapableOfFlight)
         (animal as CapableOfFlight).Fly();
}

Obviously, it would be awesome to use LINQ to do a query on that collection with a ‘where’ clause that used the “animal is CapableOfFlight” but just by itself… it’s quite nice.

Go green… don’t pollute your interfaces and keep your derived/implementer classes skinny!


Jul 13 2009

Make your types have 0 as a valid value

Category: C#,Software DevelopmentWil @ 8:07 am

Take the following simple code snippet:

internal enum MaritalStatus : byte
{
   Single = 1,
   Married = 2,
   Divorced = 3,
   Widowed = 5
}

class Program
{
   static void Main()
   {
      var maritalStatus = new MaritalStatus();
      Console.WriteLine("MaritalStatus value = " + maritalStatus);
   }
}

What is printed?  Well, 0 (zero) is printed.  That is because the .NET framework ensures that all new instances of objects get initialized to zero.

But MaritalStatus does not have a state for the value 0.  This is bad and is not what you expected.  Therefore, the solution is to “Always make your types have 0 as a valid state or value”.

If you have a business constraint where you are forced to supply the values to an enumeration like I did above, you have a problem.  But if that is not the case, you can do a couple of different things.  One, you can just leave off the numbers from the enum members entirely.  The top-most member will be set to zero; the next to one; the next to two… and so on.  The other option is to make a value that is zero.  Let’s redefine our MaritalStatus enum:

internal enum MaritalStatus : byte
{
   Undisclosed = 0,
   Single = 1,
   Married = 2,
   Divorced = 3,
   Widowed = 5
}

Now, MaritalStatus will always be “initialized” to ‘Undisclosed’ when created using the ‘new’ operator.

Of course, that also begs the question, “Why the hell are you creating an enum variable using the ‘new’ operator”.  Hey, I’m not judging.  It’s your source code.  Do whatever you like.  The software gods would smile down on you more often if you create your enums this way instead:

var maritalStatus = MaritalStatus.Married;


Jul 11 2009

Comparing C++ and C# Virtual Invocations

Category: C Plus Plus,C#,Software DevelopmentWil @ 8:22 am

I ran across this post today when I was cruising around the awesomness that is the internet:
http://blogs.msdn.com/rakkimk/archive/2007/05/11/virtual-functions-explored-c-c-examples.aspx

While Rakki did an excellent job of explaining C++ virtual table construction and invocation, I believe C# developers would really like a little more “beef” on their side of the fence.  Therefore, I will do a little comparison between the two.  The differences are huge!

In C++, you cannot call a derived class virtual method from a base class constructor because the derived class virtual table hasn’t been created yet. In C#, you absolutely can. That is a major difference!

For example, take this code in C++:

class Base
{
   public:
   // All virtual method calls in constructors are static; not dynamic.
   Base ()  { Foo(); }
   virtual void Foo() { cout << "Base::Foo" << endl; }
};
class Derived : public Base
{
public:
   Derived () { Foo(); // Calls Derived::Foo }
   virtual void Foo() { cout << "Derived::Foo" << endl; }
};
int main ()
{
   Derived derived;
}

This displays:
Base::Foo
Derived::Foo

Now, take the same code in C#:

public class Base
{
   public Base () { Foo(); }
   public virtual void Foo() { Console.WriteLine("Base::Foo"); }
}
public class Derived : Base
{
   public Derived () { Foo(); }
   public override void Foo() { Console.WriteLine("Derived::Foo"); }
}
class Program
{
   static void Main() { new Derived(); }
}

This displays:
Derived::Foo
Derived::Foo

Why? Because in C#, the virtual table has already been setup. So when the base class constructors get called, the virtual method invocation inside the constructor is truly virtual and the actual derived class instance being created is invoked (dynamically). If this is not the behaviour you want, you need to use ‘new virtual’ on each derived class instead of ‘override’. If you do that, you will get the same behaviour as in C++.

Enjoy!

Tags:


Apr 24 2008

The Joining of STA & MTA

Category: C#,Multithreading,Software DevelopmentWil @ 11:46 am

My mother-in-law was fiercely opposed to her daughter moving into my apartment.  That’s an understatement.  We sort of cared but really wanted to live together… in the same apartment.

Ok, enough with the segue! I have a WCF/WPF application that is MTA and I needed to access the print functionality down inside WPF.  Well, those controls are really picky and will yell at you and simply refuse to work if you don’t instantiate and call them from an STA thread.

No problem right?!  Well, that’s what I thought.  I mean, all I really need to do is to create a new thread and specify the apartment before it starts and then make the necessary calls.  Sounds simple enough.  Let’s take a stab at that…

[STAThread]
public string PrintSpecificLabelStock_STA
(
   LabelRequestPrintMetadata labelRequestPrintMetadata_
)
{
   Exception error = null;

   var thread = new Thread(
   delegate()
   {
      try
      {
         var labelRequestList =
            session.Execute<SpecificLabelStockQuery, List<LabelRequest>>
               (labelRequestPrintMetadata_, session);
         PrintLabelRequests(labelRequestList.ToArray());
      }
      catch (Exception ex_)
      {
         error = ex_;
      }
   });
   thread.SetApartmentState(ApartmentState.STA);
   thread.Start();
   thread.Join();

   return error == null ? string.Empty : error.Message;
}

Well, that doesn’t work.  The application locks up when the thread starts… or more specifically, when the call to Join is made.  Evidently, the unholy joining of two separate apartments is also disavowed by more than just mother-in-laws-to-be!  The workaround/fix is below:

[STAThread]
public string PrintSpecificLabelStock_STA
(
   LabelRequestPrintMetadata labelRequestPrintMetadata_
)
{
   Exception error = null;
   var resetEvent = new ManualResetEvent(false);
   var thread = new Thread(
   delegate()
   {
      try
      {
         var labelRequestList =
            session.Execute<SpecificLabelStockQuery, List<LabelRequest>>
               (labelRequestPrintMetadata_, session);
         PrintLabelRequests(labelRequestList.ToArray());
      }
      catch (Exception ex_)
      {
         error = ex_;
      }
      finally
      {
         resetEvent.Set();
      }
   });

   thread.SetApartmentState(ApartmentState.STA);
   thread.Start();
   resetEvent.WaitOne();

   return error == null ? string.Empty : error.Message;
}

Enjoy!

Tags: ,


Jan 30 2008

C# 3.0 Extension Methods

Category: C#,Software DevelopmentWil @ 11:56 am

So the interview question goes, “Does C# support multiple inheritance?”  Before C# 3.0, the answer was to not answer that with a yes/no.  The best answer would have been, “C# supports the ability to implement multiple interfaces but can only inherit from one concrete class.”

Take this code snippet:

public interface IContractOne
{
}

public class ContractImplementer : IContractOne
{
}

ContractImplementer “implements” the IContractOne interface… even though it does not define much of a “contract” signature.

Now, using the new C# 3.0 “Extension Method” feature, we can extend the IContractOne interface.  That’s right… we can actually add “implementation” to an interface… sort of.

static public ExtendsIContractOne
{
   static public void Foo (this IContractOne)
   {
      Console.WriteLine("Welcome to pseudo multiple inheritance! (sort of)");
   }
}

Now if you had a console application main method coded like this:

static public void main ()
{
   ContractImplementer contractImplementer = new ContractImplementer();
   // Now call through the IContractOne interface to the Foo method…
   contractImplementer.Foo();
}

Practical purposes?  You’ll know when you get there.

For now, this is a cool/neat language feature.

Tags:


Next Page »
Get Adobe Flash playerPlugin by wpburn.com wordpress themes