Try-Catch-FAIL

Failure is inevitable.

Two things missing from C#

clock March 11, 2010 08:07 by author Matt

While building some ugly code to walk the Lucene.NET Query graph, I found myself needing two bits of functionality from C# that it sadly doesn’t provide.  There are arguments for and against each of these, but they certainly would have saved me some pain today.

Switching off of System.Type

The Lucene query graph is a nasty beast.  There’s an abstract base Query class, but no common way to iterate through the graph and extract criteria.  Instead, you have to process each concrete type separately.  An easy way to do this would be to use a switch statement off of the concrete query type and execute the corresponding logic to process the type.  Unfortunately, the C# switch statement only supports types that are convertible to Integer (and strings).  There are solutions, such as this, but why isn’t it built in to the framework?  Peter Hallam explains the reasons, but I don’t agree with most of his argument. Visual Basic’s equivalent of a switch statement allows for case statements to “overlap”, and it doesn’t seem to be causing catastrophic problems there.  I think it’s actually quite intuitive to expect that only the first matching case statement would be executed.  In any case, I’d love to see this added to C#.

Using ‘yield return’ to directly return an IEnumerable

The ‘yield return’ statement is incredibly useful, but I’ve found myself on multiple occasions using it to enumerate a hierarchical object graph.  In such situations, it’s quite annoying that I can’t just ‘yield return’ the entire child object IEnumerable list at once.  Instead, I have to manually iterate the child list and ‘yield return’ each result individually.  I see no reason (at all) why this extra step should be necessary.   Wes describes a possible way to implement this feature, and there’s a (closed as won’t fix) issue on Microsoft Connect with a slew of votes.

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Simplified unit testing for ASP.NET MVC JsonResult

clock May 7, 2009 01:45 by author Matt

There are quite a few examples floating around on the web that describe how to test your JsonResult objects to make sure the data was correctly packaged.  They all follow the same basic pattern: mock out core ASP.NET objects (such as ControllerContext, HttpResponse, and HttpContext), call JsonResult.ExecuteResult, recover what was written to HttpResponse.Output, and deserialize it.  Sure, this approach works, but in the same manner as cleaning your house out by lighting it on fire.  It’s way overkill.  There’s a much easier way.  For simple objects, just cast JsonResult.Data:

   1: string value = "Hello, there!";
   2:  
   3: JsonResult result = new JsonResult { Data=value };
   4:  
   5: //SURPRISE!
   6: Assert.AreEqual(value, (string)result.Data);

Yeah, that seems fairly obvious.  You don’t even need the explicit cast there, I just threw it in to prove the point.  But what about anonymous types?  Easy:

   1: var value = new { Id=5, Something="Else" };
   2:  
   3: JsonResult result = new JsonResult { Data=value };
   4:  
   5: IDictionary<string,object> data = new RouteValueDictionary(result.Data);
   6:  
   7: Assert.AreEqual(5, data["Id"]);
   8: Assert.AreEqual("Else", data["Something"]);

See, easy! “But what about arrays of anonymous types?!?!?” Do not fret, LINQ to the rescue:

   1: var values = new[]
   2:                  {
   3:                      new { Id = 5, Something = "Else" },
   4:                      new { Id = 6, Something = "New" },
   5:                      new { Id = 7, Something = "Old" },
   6:                  };
   7:  
   8: JsonResult result = new JsonResult { Data = values };
   9:  
  10: IDictionary<string, object>[] data = ((object[]) result.Data).Select(o => new RouteValueDictionary(o)).ToArray();
  11:  
  12: Assert.AreEqual(5, data[0]["Id"]);
  13: Assert.AreEqual(6, data[1]["Id"]);
  14: Assert.AreEqual(7, data[2]["Id"]);
  15: Assert.AreEqual("Else", data[0]["Something"]);
  16: Assert.AreEqual("New", data[1]["Something"]);
  17: Assert.AreEqual("Old", data[2]["Something"]);

Again, easy!

Alright, I know what you’re thinking.  “But Matt, the other solutions are all way more complicated, plus you’re cheating, that isn’t what JsonResult.ExecuteResult is going to do!” Well, you’re half-right, the other solutions are way more complicated, but this is actually simulating precisely what ExecuteResult will do.  Don’t believe me?  Pop it open in Reflector, or just browse the source (man I love Subversion).  It isn’t doing anything magical, it’s just using JavaScriptSerializer.  My solution just cuts out the middle man and doesn’t require you to mock out a bunch of complicated objects.

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


First Impressions of Resharper 4.5

clock March 18, 2009 03:05 by author Matt

Well, I broke down and installed the new beta of Resharper a few minutes ago.  This was motivated by the fact that I was working with our gigantic DAL, and 4.1 was really slowing me down (like it always does on large files).  Resharper 4.5 didn’t boast improvements for large files, just large solutions, but I thought I’d try it anyway. 

So, first thing I notice is that the solution (about 50 projects) opens slightly faster, maybe.  It was really too close to tell without using a stopwatch.  Color me not impressed. 

Next, my Agent Smith plug-in was gone.  It’s a really handy plug-in, so I checked the site, saw that there was a version for 4.5, uninstalled my old 4.1 version of the plug-in, installed the 4.5 version, and thought I would be good to go.  WRONG.

Resharper puked on load with this error: Could not load type
'JetBrains.UI.Shell.PluginSupport.PluginDescriptionAttribute' from
assembly 'JetBrains.Platform.ReSharper.UI, Version=4.5.1182.15,
Culture=neutral, PublicKeyToken=1010a0d8d6380325'
.  Looks like Agent Smith doesn’t work with the beta.  Fortunately, someone has already posted fixed binaries here.

Now, all seems well.  I load the DAL back up, but I’m very disappointed to see that performance has not improved much.  Even typing in such a large file causes all kinds of slowness.  It appears to be a little better than 4.1, but it’s hardly noticeable.

Oh well, I still love Resharper.  It’s a great product.  I guess I just expected/hoped for a little more out of a release that was focused on improving performance.

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Service DashBored: easily monitor your application's health

clock January 6, 2009 02:08 by author Matt

James Kolpack has posted a new project and article on CodeProject for monitoring the health of various resources.  Thanks to it's use of dependency injection, the Service DashBored is easily extensible, so if one of the built-in end points isn't sufficient for your scenario, you can easily write your own.  And yes, he meant to spell it that way. 

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Unit Testing in .NET Part 3 - Asserting That Your Code Rocks

clock December 16, 2008 07:52 by author Matt

In the previous entries in this series, you've learned about the basics of unit testing, and you've seen how to create a very basic unit test.  In this post, you will learn how to fully use NUnit's Assert class to create a full suite of unit tests.  This post builds off the sample described in the previous post, so be sure to check it out if you want to follow along.

Asserting Equality

In the last post, you saw one example of how to use the Assert.AreEqual method to verify that two objects are equal.  As you will soon see, most methods on the Assert class have a ton of overloads.  You can think of the method as having two levels of overloads: the first for all the various types you could pass in (it has specific overloads for most primitive types as well as more generic versions that work with anything that derives from object), and the second level for controling the message that is shown when the Assert fails.  The type-based overloads are self-explanatory and are handled by the compiler for you automatically, so we'll ignore those and focus on the overloads that look like Assert.AreEqual(expected,actual,message) and Assert.AreEqual(expected,actual,message,params).  Let's incorporate one of these overloads into our unit test from the last post.  Here's the original, unmodified test:

   1: /// <summary>
   2: /// Verifies that the balance increases
   3: /// by the appropriate amount.
   4: /// </summary>
   5: [Test]
   6: public void Deposit_AddsValueToBalance()
   7: {
   8:     Account account = new Account();
   9:     //account.Balance is currently zero.
  10:     account.Deposit(100);
  11:   
  12:     Assert.AreEqual(100, account.Balance);
  13: }

Let's change our assumption about what the Deposit method should be doing.  Let's say that this is an awesome bank that automatically adds a 10% match to anything that you deposit.  We could just change the first parameter to Assert.AreEqual to 110, but what happens if we run that test?  All you will see is the 'expected (110), actual (100)' message.  It doesn't tell you much about why 110 was expected.  That's where the third parameter comes in handy:

   1: /// <summary>
   2: /// Verifies that the balance increases
   3: /// by the appropriate amount.
   4: /// </summary>
   5: [Test]
   6: public void Deposit_AddsValueToBalance()
   7: {
   8:     Account account = new Account();
   9:     //account.Balance is currently zero.
  10:     account.Deposit(100);
  11:  
  12:     Assert.AreEqual(110, account.Balance, "Deposit bonus was not applied!");
  13: }

Now when you run the test, you will see the helpful message that was supplied as the third parameter to AreEqual.  The fourth parameter, a params array of objects, behaves like the String.Format method: the third parameter becomes a format string, and the fourth parameter is the set of values to insert into the format string.  This could be useful for logging additional information about the unit test failure.

For both double and float types, the AreEqual method has an additional set of overloads that look like Assert.AreEqual(expected,actual,tolerance).  The tolerance parameter allows you to tell NUnit how close two floating-point values have to be in order to be considered equal.  Going back to our Deposit_AddsValueToBalance test, what if the bonus wasn't *quite* 10%, but was more like 9.75989%?  Well, we could calculate exactly what the bonus would be and pass that in as the expected value, then apply it, or we could specify a tolerance of 0.01 and leave the expected value as 110, like so:

   1: /// <summary>
   2: /// Verifies that the balance increases
   3: /// by the appropriate amount.
   4: /// </summary>
   5: [Test]
   6: public void Deposit_AddsValueToBalance()
   7: {
   8:     Account account = new Account();
   9:     //account.Balance is currently zero.
  10:     account.Deposit(100);
  11:  
  12:     Assert.AreEqual(110, account.Balance, 0.01, "Deposit bonus was not applied!");
  13: }

In addition to primitive types, NUnit has some "special" support for Arrays and Collections.  Typically in the .NET world, Equality is determined by an object's Equals method. Derived types are responsible for overriding that method if they wish to define equality as anything other than the default behavior inherited from the object class.  NUnit fudges this definition a bit for Collections and Arrays: two collections (or arrays) are considered equal if they have the same number of items and all their corresponding elements are equal. 

There is a corresponding inverse method to AreEqual called (not surprisingly) AreNotEqual.  The obvious difference is that AreNotEqual verifies that two objects are different from one another.  AreNotEqual has the same set of overloads as its complementary method.

Asserting Sameness

Next up is the AreSame method.  You may be wondering "what's the difference between 'same' and 'equal'?".  Objects A and B are equal if A.Equals(B) returns true.  Remember that by default all objects inherit an Equals method from the base object class, and that derived classes can implement custom equality checks as needed, so the exact definition of equal depends on what you are comparing.  'Same' is much simpler: objects  A and B are the same if they point to the exact same object in memory. 

The difference between 'equal' and 'same' may sound a bit confusing if you aren't comfortable with the concept of pointers and object references, so check the documentation here if you are still unclear.

To demonstrate this difference, let's create a new method that looks up account information and verify that repeated calls to the method return the same account information instance.  NOTE: I am intentionally not doing things in a test-driven manner right now.  I don't want to muddy the waters with trying to explain that concept at the same time I'm explaining the asserts.  A proper treatment of test-driven development is coming Real Soon(tm)!

First, let's add some new properties to our Account class along with an overloaded Equals method:

   1: /// <summary>
   2: /// A bank account.
   3: /// </summary>
   4: public class Account
   5: {
   6:     #region Public Properties
   7:  
   8:     /// <summary>
   9:     /// The ID of the account.
  10:     /// </summary>
  11:     public int AccountID { get; private set; }
  12:  
  13:     /// <summary>
  14:     /// The name of the account owner.
  15:     /// </summary>
  16:     public string Owner { get; private set; }
  17:  
  18:     /// <summary>
  19:     /// The current account balance.
  20:     /// </summary>
  21:     public float Balance { get; private set; }
  22:  
  23:     #endregion
  24:  
  25:     #region Public Methods
  26:     
  27: ----Snip----
  28:  
  29:     /// <summary>
  30:     /// Compares the current object to the specified object.
  31:     /// </summary>
  32:     /// <param name="obj"></param>
  33:     /// <returns>True if the accounts have the same AccountID,
  34:     /// false otherwise.</returns>
  35:     public override bool Equals(object obj)
  36:     {
  37:         Account account = obj as Account;
  38:  
  39:         if (account == null)
  40:         {
  41:             return false;
  42:         }
  43:         else
  44:         {
  45:             return AccountID == account.AccountID;
  46:         }
  47:     }
  48:  
  49:     /// <summary>
  50:     /// When you override Equals, you have to override
  51:     /// GetHashCode, too...
  52:     /// </summary>
  53:     /// <returns></returns>
  54:     public override int GetHashCode()
  55:     {
  56:         return AccountID.GetHashCode();
  57:     }
  58:  
  59:     #endregion
  60: }

Next, let's add a method to look up and return a 'dummy' Account object on demand:

   1: /// <summary>
   2: /// Gets the specified account.
   3: /// </summary>
   4: /// <param name="accountID"></param>
   5: /// <returns></returns>
   6: public static Account Lookup(int accountID)
   7: {
   8:     return new Account {AccountID = accountID, Owner = "John Doe"};
   9: }

Finally, let's create our test:

   1: /// <summary>
   2: /// The Lookup should return the exact same instance
   3: /// for all lookups on a specific ID.
   4: /// </summary>
   5: [Test]
   6: public void Lookup_ReturnsSameInstance()
   7: {
   8:     Account account = Account.Lookup(1);
   9:  
  10:     Assert.AreSame(account, Account.Lookup(1));
  11: }

Go ahead and build the project and run the test.  What happened?  The test failed because even though we are returning an identical object for both calls, we aren't actually returning the same object.  Let's correct that by storing some static dummy Account instances; we'll return one of these instead of creating a new instance from now on:

   1: /// <summary>
   2: /// These are our dummy accounts.
   3: /// </summary>
   4: private static Account[] mAccounts = new Account[]
   5: {
   6:     new Account{ AccountID = 1, Owner = "John Doe" },
   7:     new Account{ AccountID = 2, Owner = "Jane Doe" }
   8: };
   9:  
  10: /// <summary>
  11: /// Gets the specified account.
  12: /// </summary>
  13: /// <param name="accountID"></param>
  14: /// <returns></returns>
  15: public static Account Lookup(int accountID)
  16: {
  17:     //Arrays are 0-based, accountIDs are 1-based, so we shift them.
  18:     return mAccounts[accountID - 1];
  19: }

Build and re-run the test, and you should get a success message.

Similar to the AreEqual method, the AreSame method has a logical inverse: the AreNotSame method. 

Asserting Greatness

NUnit includes four methods (with overloads) for asserting various inequalities: Greater, GreaterOrEqual, Less, and LessOrEqual.  The intent of these methods should be obvious, but they differ in one major one from the other assertions we've seen so far.  Recall that the basic versions of both AreEqual and AreSame took an expected argument first and the actual value second.  Applying that same logic, you might expect that expressing the inequality x is greater than y would look like Assert.Greater(y,x), but it's actually the opposite.  I can't tell you how many times I've seen this inconsistency bite developers; it doesn't help that the parameters have less-than-helpful names, like arg1 and arg2.  I don't know why they couldn't have used something more obvious and intuitive, like maybe left and right...

Enough complaining, Let's write some code!  Let's add a new deposit to our account class called RandomDeposit.  This method is very different from our standard Deposit method.  Instead of depositing the specified amount, RandomDeposit will deposit a random amount that is anywhere from 0.5 to 1.5 times the specified amount.  The method looks like so:

   1: /// <summary>
   2: /// Deposits a random amount that is between 0.5 
   3: /// and 1.5 times the specified amount.
   4: /// </summary>
   5: /// <param name="amount"></param>
   6: public void RandomDeposit(float amount)
   7: {
   8:     Random rand = new Random();
   9:     double multiplier = rand.NextDouble();
  10:  
  11:     Balance += (float)(amount*(0.5 + multiplier));
  12: }

Because of the randomness in the method, it's going to be very hard to write a unit test using the Assert.AreEqual method.  Instead, we'll use the GreaterOrEqual method to assert that the deposited amount is at least 0.5 times the amount we deposited.  Here's the unit test:

   1: /// <summary>
   2: /// The method should deposit between 0.5 and 1.5
   3: /// times the specified amount.
   4: /// </summary>
   5: [Test]
   6: public void RandomDeposit_DepositsExpectedAmount()
   7: {
   8:     Account account = new Account();
   9:  
  10:     account.RandomDeposit(100);
  11:     Assert.GreaterOrEqual(account.Balance, 50);
  12:     Assert.LessOrEqual(account.Balance, 150);
  13: }

If you aren't already building and testing by habit, go ahead and build the project and run the new test. 

Asserting Typeiness (If Steven Colbert can do it, so can I!)

The Assert class includes methods for asserting things about the type of an instance.  You can check whether or not an object is of a given type using the IsInstanceOfType method.  The first parameter is the expected type of the object, the second parameter is the actual object.  Let's make our Account class implement the ICloneable interface, then write a test to verify that our clone actually is of type Account:

   1: /// <summary>
   2: /// A bank account.
   3: /// </summary>
   4: public class Account : ICloneable
   5: {
   6: ----SNIP----
   7: /// <summary>
   8: /// Clones the current account.
   9: /// </summary>
  10: /// <returns></returns>
  11: public object Clone()
  12: {
  13:     return new Account {AccountID = AccountID, Balance = Balance, Owner = Owner};
  14: }
  15: ----SNIP----
  16: }

Here's the corresponding test case:

   1: /// <summary>
   2: /// Verifies that a complete clone of the account
   3: /// is returned.
   4: /// </summary>
   5: [Test]
   6: public void Clone_ReturnsAccountClone()
   7: {
   8:     Account account = Account.Lookup(1);
   9:  
  10:     object clone = account.Clone();
  11:  
  12:     Assert.IsInstanceOfType(typeof (Account), clone);
  13: }

The IsInstanceOfType and IsAssignableFrom methods are very similar.  Under the covers, they're just calling the corresponding members of the System.Type class.  Check the documentation on MSDN if you are curious about the subtle differences between the two methods, but for the most part, you can use them interchangeably. 

As with most assert methods, there are various overloads of both IsAssignableFrom and IsInstanceOfType.  Each also has a set of complementary Not methods: IsNotAssignableFrom and IsNotInstanceOfType.

Asserting Nothingness

Sometimes the right result is a null result.  Let's look again at our Account.Lookup method.  Right now, we're not really handling the case of an account ID that doesn't exist.  Let's modify the code so that it returns null when given an invalid account ID:

   1: /// <summary>
   2: /// Gets the specified account.
   3: /// </summary>
   4: /// <param name="accountID"></param>
   5: /// <returns></returns>
   6: public static Account Lookup(int accountID)
   7: {
   8:     if (accountID < 1 || accountID > mAccounts.Length)
   9:     {
  10:         return null;
  11:     }
  12:  
  13:     //Arrays are 0-based, accountIDs are 1-based, so we shift them.
  14:     return mAccounts[accountID - 1];
  15: }

And let's write a new test case to verify this:

   1: /// <summary>
   2: /// The lookup should return null when given an ID
   3: /// that doesn't correspond to an account.
   4: /// </summary>
   5: [Test]
   6: public void Lookup_ReturnsNullForInvalidId()
   7: {
   8:     Assert.IsNull(Account.Lookup(0));
   9:  
  10:     Assert.IsNotNull(Account.Lookup(2));
  11: }

Here we've used the Assert.IsNull method.  This is a very simple assert: it simply checks that the parameter is null.  Like everything else, it has a complementary method that will test that something is not null. 

Asserting Truthiness (or Falsiness)

Everything we've asserted so far could actually be expressed using one of the most basic assertions: IsTrue.  This method asserts that a boolean input is true.  It has a complementary IsFalse method that can be used to assert that an input is false.  These methods can be used to test anything that you can express as a boolean condition.  Let's rewrite our previous Lookup test using only IsTrue instead of IsNull to see this:

   1: /// <summary>
   2: /// The lookup should return null when given an ID
   3: /// that doesn't correspond to an account.
   4: /// </summary>
   5: [Test]
   6: public void Lookup_ReturnsNullForInvalidId()
   7: {
   8:     Assert.IsTrue(Account.Lookup(0) == null);
   9:     //Assert.IsNull(Account.Lookup(0));
  10:  
  11:     Assert.IsTrue(Account.Lookup(2) != null);
  12:     //Assert.IsNotNull(Account.Lookup(2));
  13: }

The test should produce identical output because it is logically equivalent to the original.  You might be tempted to just say "forget about all these other asserts, I'll just use IsTrue for everything!", but that's a terrible idea.  The various other assertions give you a lot more information when something goes wrong than IsTrue will.  For example, if GreaterThan fails, it will tell you the values of both parameters.  If you expressed the test using only IsTrue, you would get a very unhelpful message that says "Expected: True, Actual: False".  Sure, you can probably work backwards, add some logging, etc, to figure out what's going on, but why not use the more powerful GreaterThan method to begin with?

Asserting Failuriness

Sometimes you just want a test to fail. Maybe the test isn't finished, or the test couldn't perform some setup correctly, or maybe you need to test for something that is beyond what the built-in assertion methods can handle.  Assert.Fail to the rescue!  Calling this method will instantly fail a test (assuming you haven't done anything silly like wrapped the call with a try-catch block, which we will look at in a future post). 

Asserting Exceptioniness

We've tested that things work so far, but how do we test that things explode?  Right now, there's nothing in our Deposit method that prevents us from depositing negative amounts.  Let's add some logic to throw an exception:

   1: /// <summary>
   2: /// Deposits the specified amount.
   3: /// </summary>
   4: /// <param name="amount"></param>
   5: public void Deposit(float amount)
   6: {
   7:     if (amount <= 0)
   8:     {
   9:         throw new ArgumentOutOfRangeException("amount", amount, "Must be greater than zero.");
  10:     }
  11:  
  12:     Balance += amount;
  13: }

Error-handling code is good, but it still needs to be tested.  NUnit has the ExpectedException attribute that you can use to verify that an exception is thrown, but I hate this attribute.  What the attribute is really doing is verifying that something somewhere in your test case is throwing an exception, not that the exception is actually coming from where you want it to come from.  Instead, I prefer to go with this model:

   1: /// <summary>
   2: /// The method should throw an ArgumentOutOfRangeException
   3: /// if you pass in a negative value.
   4: /// </summary>
   5: [Test]
   6: public void Deposit_ThrowsExceptionOnNegativeAmount()
   7: {
   8:     Account account = new Account();
   9:  
  10:     try
  11:     {
  12:         account.Deposit(-100);
  13:         //The following line will only be executed if the Deposit method
  14:         //failed to throw an exception.
  15:         Assert.Fail("Expected ArgumentOutOfRangeException was not thrown!");
  16:     }
  17:     catch (ArgumentOutOfRangeException)
  18:     {
  19:         //Ok, this is an expected exception.
  20:     }
  21: }

It requires a bit more code, but this version verifies that the correct type of exception is thrown in exactly the right spot.

Other Ways to Assert RoXXorness

The methods we've looked at so far are just the ones that I have found myself using often over the last several years.  NUnit includes other methods that you can use to assert various things about your objects, including:

  • Assert.Contains - Given an object and a list, this method asserts that the collection contains the specified object.
  • Assert.IsEmpty - Given a collection (or a string), asserts that the object contains no items.
  • Assert.IsNaN - Both double.NaN represent the 'not-a-number' condition (often caused by division by zero).  You can test for this condition using the IsNaN assert.

There is even more...

Recent versions of NUnit have added additional utilities, asserts, etc. to simplify your testing.  You can find out more about them here.  We might look at those in a future post, but I really don't find myself using most of them in my day-to-day testing, and I think most developers can get by just fine without them.

In the next post in this series, we'll look at some more complicated testing scenarios as well as common testing problems and strategies for overcoming them.

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


I declare victory for C# over C!

clock December 3, 2008 10:32 by author Matt

Alright, that's not quite fair, but anyone that assumes that C# is going to be slow just because Java is making a big mistake.  One of my classmates made this mistake, and it should have cost him $5, but I chickened out and wouldn't take the bet.  Anyway:

We had a programming assignment to find the average number of colors to color a graph.  I won't go into the details, but suffice to say that we had very similar solutions in terms of algorithmic design (in theory my algorithm should have been faster, but it looks like its advantage is minimal in practice), and he thought his program would smoke mine due to our choices in language and platform.  I chose C# and .NET 3.5 running on Windows, he chose straight-up C running on MacOS.  We both ran our programs on MacBook's with identical processors.  Even *I* expected the C program to win out.  When I use .NET, I know that I am giving up some performance in exchange for an improved development experience... or so I thought.

We fired up our programs in dramatic fashion, then waited for them to complete.  10 minutes later, we had our winner: C# had completed the task ahead of C.  The C program wrapped up around the 14 minute mark.  I love C# and .NET, and though I expected C# to be close to C, I never expected it to be faster. 

Despite the results, I still think the C version should have been faster; there must be some minor algorithmic, implementation, or environment difference that is causing the results.  Still, this does demonstrate that C# is no slouch on the performance front.

Oh, and for anyone that likes Java: I talked to people who implemented the same assignment using Java, and their programs took *hours* to run for the same problem size.  Suck on that, Java! :P

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Calculating aggregates with Microsoft Parallel Extensions for .NET

clock November 24, 2008 09:47 by author Matt

The Parallel Extension for .NET (aka PFX) is a new API coming to .NET 3.5 (and included out-of-the-box with .NET 4.0) that greatly simplify and enhance the parallel-processing story in .NET.  Sure, we've got Thread and ThreadPool, but these classes are very lacking.  Fortunately, PFX is a huge improvement.  Be sure to check out their blog and the Parallel Computing Center on MSDN for more information.

One of the things I ran into last week was the need to calculate an average of a series of numbers.  Each number was computed by a long-running method, and since each number was independent, it was a good candidate for parallelization.  While parallelzing a set of operations is trivial with PFX, parallelizing an aggregation like this isn't as straight forward.  There's a "right" way to do it and a "wrong" way to do it.  The simplest answer is to use some sort of synchronization primitive in your parallelized code to safely increment the running sum variable, like this:

   1: Parallel.ForEach(someObjects, 
   2:                     theObject =>
   3:                         {
   4:                             int value = CalculateValue(theObject);
   5:                             Interlocked.Add(ref sum, value);
   6:                         });

However, this is going to cause a lot of unnecessary thread synchronization that's going to harm performance.  A better (but more complicated way) is to have each thread keep its own running sum, then combine each thread's output at the end into a global sum.  On this front, I found the documentation and (limited) samples to be a little less helpful than I would have liked (especially for such a trivial problem), but I managed to piece together the solution easily enough:

   1: Parallel.ForEach(someObjects, 
   2:                     () => 0,
   3:                     (theObject, index, localSum) =>
   4:                         {
   5:                             localSum += CalculateValue(theObject);
   6:                         },
   7:                         localSum => Interlocked.Add(ref sum ,localSum));

This is a little more complicated, so let's walk through it: the first parameter is the set of objects to ForEach over in parallel.  The second parameter is a delegate that returns an object to use for each thread's local state.  This can be any object you want, but in this case, since we're calculating a sum, it's just an int, initialized to zero.  Next is the actual code that we want to execute in parallel.  This time, it takes in three parameters instead of just one: the object to process, the index of the object in the enumerable (which this code isn't using, but has to include since that's how the delegate is defined), and the thread-local state, which in our case is the local counter (which we initialized to zero).  Again, we calculate a sum, but this time it's just tacked on to our local sum.  Finally, we have another expression that takes the integer localSum as input.  This is invoked once per thread at the end of the thread's work.  It takes the thread's local sum and adds it to our global, shared sum.  Since this could be invoked on multiple threads at once, it still needs to be synchronized, but unlike the original parallel implementation, we're only doing synchronization once per thread instead of for each item processed by the thread.  Pretty simple, but a bit verbose.  Something more like this would be preferable (and more intuitive) for trivial problems like this:

   1: Parallel.Sum(someObjects),
   2:                 theObject => CalculateValue(theObject),
   3:                 ref sum);

I thought about wrapping this up in an extension method, but you can't define extension methods for static classes, so that's out of the question. :(  Still, I'm very excited about the changes coming to .NET to better enable us developers to leverage modern-day multi-core systems. 

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Friday Grab-Bag

clock November 21, 2008 01:11 by author Matt

A severe lack of sleep and the "too many irons in the fire" syndrome has left me a tad frazzled, so instead of a well-written (I see you laughing!) post, you get a collection of random thoughts and observations:

Too much lambda?

I wonder if I'm relying too heavily on lambda expressions.  What do you think, is this going too far (extracted from one of my unit tests):

   1: /// <summary>
   2: /// Verifies that the correct number of graphs are returned
   3: /// for various sizes.
   4: /// </summary>
   5: [Test]
   6: public void EnumerateGraphs_ReturnsCorrectNumberOfGraphs()
   7: {
   8:     //The number of possible graphs is 2^((n*(n-1)/2) where n is the number of edges.
   9:     //This expression will calculate it.
  10:     Func<int, int> NumGraphs = (n) => (int)Math.Pow(2, (n*(n - 1)/2));
  11:  
  12:     Assert.AreEqual(NumGraphs(1), Graph.EnumerateGraphs(1).Count());
  13:  
  14:     Assert.AreEqual(NumGraphs(2), Graph.EnumerateGraphs(2).Count());
  15:  
  16:     Assert.AreEqual(NumGraphs(3), Graph.EnumerateGraphs(3).Count());
  17:  
  18:     Assert.AreEqual(NumGraphs(4), Graph.EnumerateGraphs(4).Count());
  19:  
  20:     Assert.AreEqual(NumGraphs(5), Graph.EnumerateGraphs(5).Count());
  21:  
  22:     Assert.AreEqual(NumGraphs(6), Graph.EnumerateGraphs(6).Count());
  23: }

See line 10 for what I mean.  The formula for counting the number of possible undirected graphs with a given number of vertices is quite simple, and it just didn't "feel" like it needed to be a method; I just wanted to alias the expression so that I could easily reuse it.  Is this a bad thing?  Should I have created a private helper method instead (complete with comments and all that jazz)?

Parallel Extensions == Awesome

One of my assignments for grad school was to create a graph coloring application (I won't get in to details, and no, I won't be posting the code for that), but if you've ever messed with graph coloring, you know that the time taken to find a valid coloring increases greatly as the complexity of your graph increases.  Well, I wrote my solution in C#, and I wasn't satisfied with the runtime, so I used the Parallel Extensions June CTP release to parallelize it.  The improvements were impressive.  Sequentially, calculating the average number of colors needed to "colorize" all graphs of size <= 8 took about 1.5 hours (in DEBUG) on a dual-dual core Opteron workstation, with only one core saturated (a huge waste).  I applied Parallel.ForEach in the problem, and the run-time dropped to 28 minutes.  That's impressive. :)

Parallel Extensions == Ugly

Despite the huge performance gains that are available by leveraging multiple cores, I still think the API has a long way to go.  Here's the sequential work-horse of my algorithm:

   1: foreach (Graph graph in Graph.EnumerateGraphs(numVertices))
   2: {
   3:     //Keep a running count of how many graphs there are.
   4:     numGraphs++;
   5:     
   6:     //Tally how many colors this graph took.
   7:     totalColors += FindMinimumColors(graph);
   8: }

And here's the parallel version:

   1: Parallel.ForEach(
   2:     Graph.EnumerateGraphs(numVertices),
   3:     () => (new Pair<int, int>()),
   4:     (graph, index, state) =>
   5:         {
   6:             int minColors = FindMinimumColors(graph);
   7:             //The left half of the pair is the count, the right half is the color sum
   8:             state.ThreadLocalState.Left++;
   9:             state.ThreadLocalState.Right += minColors;
  10:         },
  11:     partial =>
  12:         {
  13:             Interlocked.Add(ref numGraphs, partial.Left);
  14:             Interlocked.Add(ref totalColors, partial.Right);
  15:         }
  16: );

As you can see, it looks like the unreadable code fairy sprinkled pixie dust all over the sequential version, then kicked it in the knees and took its wallet.  There needs to be a better, more readable way to do aggregations like this. 

The End?

Yeah, for this week anyway.  Next week I hope to write more about DeepCrawler.NET (there's a chance that my current employer may even adopt the code, which means I could actually get paid to work on it!), but if anyone would rather see/hear about something else, let me know. 

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Dynamic objects in C# 4.0

clock November 5, 2008 00:43 by author Matt

I was going to write up my feelings on the new 'dynamic' features coming with C# 4.0, but this basically sums up my feelings exactly.  Are dynamic references a useful feature?  Sure, there are going to be times when this is really handy.  Can it be misused?  Most definitely.  Will it be misused?  Almost certainly. Sometimes, having to jump through the hoops of strong-typing is a really, really good thing.

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Bridging the Java-.NET Gap: foreach-ing an Enumeration

clock November 3, 2008 10:08 by author Matt

My fun with IKVM.NET continues this week as I utilize Weka from .NET (just a fun note, but the .NET-compiled version is insanely faster than the Java version doing the exact same thing; suck on that, Java fans!).  For the most part, everything has been swell.  The hardest part is trying to decipher research methodologies to replicate the systems they describe.  Still, I've run into a few snags when working with the .NET versions of Weka, the first of which is that you can't foreach over a Java Enumeration.  For example, consider the following:

   1: //THE FOLLOWING DOESN'T COMPILE!
   2: //foreach (weka.core.Instance instance in instances.enumerateInstances())
   3: //{
   4: //    //TODO: Operate on instance here.
   5: //}
   6:  
   7: Enumeration enumerator = instances.enumerateInstances();
   8: while (enumerator.hasMoreElements())
   9: {
  10:     weka.core.Instance instance = (weka.core.Instance)enumerator.nextElement();
  11:  
  12:     //TODO: Operate on instance here
  13: }

While it isn't a huge difference, being able to use foreach would obviously be simpler than having to create an instance of Enumeration, then use it to step through the items.  Fortunately, it's quite easy to generically bridge the gap so that any Enumeration can be enumerated by simply calling an extension method, like so:

   1: foreach (weka.core.Instance instance in instances.enumerateInstances().ToEnumerable())
   2: {
   3:     //TODO: Operate on instance
   4: }

How does this work?  First, we need to apply the adapter pattern to convert a Java Enumeration into a .NET IEnumerator.  Here's our adapter:

   1: /// <summary>
   2: /// Provides an adapter that can convert a Java
   3: /// Enumeration class into something that implements
   4: /// IEnumerator.  
   5: /// </summary>
   6: public class EnumeratorEnumerationAdapter : IEnumerator
   7: {
   8:     #region Private Fields
   9:  
  10:     /// <summary>
  11:     /// The class being adapted.
  12:     /// </summary>
  13:     private Enumeration mEnumeration;
  14:  
  15:     /// <summary>
  16:     /// The current object.
  17:     /// </summary>
  18:     private object mCurrent;
  19:  
  20:     #endregion
  21:  
  22:     #region Implementation of IEnumerator
  23:  
  24:     /// <summary>
  25:     /// Advances the enumerator to the next element of the collection.
  26:     /// </summary>
  27:     /// <returns>
  28:     /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
  29:     /// </returns>
  30:     /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority>
  31:     public bool MoveNext()
  32:     {
  33:         if (!mEnumeration.hasMoreElements())
  34:         {
  35:             return false;
  36:         }
  37:  
  38:         mCurrent = mEnumeration.nextElement();
  39:         return true;
  40:     }
  41:  
  42:     /// <summary>
  43:     /// Sets the enumerator to its initial position, which is before the first element in the collection.
  44:     /// </summary>
  45:     /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority>
  46:     public void Reset()
  47:     {
  48:         throw new NotSupportedException();
  49:     }
  50:  
  51:     /// <summary>
  52:     /// Gets the current element in the collection.
  53:     /// </summary>
  54:     /// <returns>
  55:     /// The current element in the collection.
  56:     /// </returns>
  57:     /// <exception cref="T:System.InvalidOperationException">The enumerator is positioned before the first element of the collection or after the last element.-or- The collection was modified after the enumerator was created.</exception><filterpriority>2</filterpriority>
  58:     public object Current
  59:     {
  60:         get
  61:         {
  62:             return mCurrent;
  63:         }
  64:     }
  65:  
  66:     #endregion
  67:  
  68:     #region Public Constructors
  69:  
  70:     /// <summary>
  71:     /// Creates an adapter for the specified enumeration.
  72:     /// </summary>
  73:     /// <param name="enumeration"></param>
  74:     public EnumeratorEnumerationAdapter(Enumeration enumeration)
  75:     {
  76:         mEnumeration = enumeration;
  77:         mCurrent = null;
  78:     }
  79:  
  80:     #endregion
  81: }

Next, we just need to write the extension method that utilizes our adapter to create an IEnumerable:

   1: /// <summary>
   2: /// Contains extension methods to simplify working with 
   3: /// <see cref="Enumeration"/> objects.
   4: /// </summary>
   5: public static class EnumerationExtensions
   6: {
   7:     /// <summary>
   8:     /// Creates a <see cref="IEnumerable"/> wrapper
   9:     /// around a <see cref="Enumeration"/>.
  10:     /// </summary>
  11:     /// <param name="enumeration"></param>
  12:     /// <returns></returns>
  13:     public static IEnumerable ToEnumerable(this Enumeration enumeration)
  14:     {
  15:         EnumeratorEnumerationAdapter adapter = new EnumeratorEnumerationAdapter(enumeration);
  16:  
  17:         while (adapter.MoveNext())
  18:         {
  19:             yield return adapter.Current;
  20:         }
  21:     }
  22: }

And like magic, you can now foreach over any Java Enumeration just like it was a .NET IEnumerable implementor.  It'd be nice if this were baked in to IKVM.NET, but for now, this simple "hack" will do the trick.

Share or Bookmark this post…
  • del.icio.us
  • DotNetKicks
  • Digg
  • msdn Social
  • Reddit
  • StumbleUpon

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


About Matt

I am an overworked (and apparently overpaid) software developer with aspirations of acquiring a PhD in Computer Science. I started off coding in C over a decade ago.  Since then, I've migrated from C to C++ and branched out to C#, PHP, VB.NET, JavaScript, and worked with a wide assortment of other languages that I hope to never deal with again (I'm looking at you, COBOL). Oh, and yes, I've written some Java.  Does that make me a bad person?

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in  anyway.

© Copyright 2009

Sign in