December 9, 2008
@ 01:09 AM

Over the past week I've had the distinct opportunity to have a first-hand look into NHProf, Ayende's upcoming profiler for NHibernate.  It's been an honor to be part of the team that is putting NHProfiler through its paces.  While NHProfiler is still in private beta it is very impressive and I want to let you peek inside.

This evening I decided to sit down and spend some time poking around an application and watch NHProfiler to see if anything seemed out of sorts.  Here's what I found:

Easy To Understand

You can get by without purchasing NHProf, from what I see there's nothing you can't "figure out" yourself.  NHProf is a lot like ReSharper or CodeRush, you can get by without it, but why would you want to?  Here's what I mean, you can pop open SQL Server Profiler and see what is being executed:

image

That's messy but take a look at how NHProf collates the data:

image

Relevant

You can sift through the SQL Server Profiler trace if you'd like to but NHProfiler does a great job in giving you the same information, just presented better.

image

From this view I can see that five queries were run and I can see that three of the same queries are being issued which might point to an area where there is some tweaking to do.

Performance Gains

We all want our applications to run faster.  We want speed and performance but often times its takes quite a bit of time to find performance problems and their subsequent fixes.  NHProfiler allowed me to very quickly find some queries that didn't need to be executing and tweak some code to eliminate those calls.  Since I can see the code that NHibernate generates I can also make modifications to query I'm submitting to NHibernate for further performance gains.

In a very short amount of time (the writing of this blog post has taken several times longer) I was able to reduce reduce data access time by a factor of nearly 10.  How do I know that, I have the hard data to prove it.

Before:

image

After:

image

Conclusion

If you use NHibernate, NHProfiler is a must.  By using NHProf to observe my applications I'm able to save my time and not have to burrow through SQL Server Profiler or wonder what is going on at the data level.  I am quickly able to observe what is going on and when and make any necessary modification and then observe the outcome.  While you can use Visual Studio without ReSharper or CodeRush many of you out there have found you just don't want to.  After using these productivity tools you find that you're able to work with less friction.  NHProfiler is the same way, you can work without it, but I highly recommend against it.

Keep your eye on Ayende's blog for information coming soon.


 
Categories: NHibernate | NHProf | Tools

One of the features that I really like in .NET 3.5 is Func<T>.  For those of you who aren't familiar with Func<T>, it is simply a delegate.  While I generally haven't seen many people who embrace delegates, it may be due to my limited exposure to different programming teams over the past few years.  Generally speaking I see frameworks latch on to many of these new features much sooner than the average web application.  In this post I want to show that Func usage is simple and within reach for you in your application(s).

The Story

As a user I can have a temporary password emailed to me if I forget my own, so that I can regain access to my account.

The Implementation

I've seen various implementations of this over the years and each one seems to want to generate some randomized set of digits and characters with the possibility of special characters in there.  Here's a possible implementation I've made leveraging the use of Func.  Take a look and then I'll break it down.

   1: public string CreateTemporaryPassword(int length)
   2: {
   3:     Func<Random, char> randomNumber = rnd => (char) rnd.Next(48, 58);
   4:     Func<Random, char> randomCharacter = rnd => (char) rnd.Next(97, 123);
   5:  
   6:     var funcArray = new[] {randomNumber, randomCharacter};
   7:     var chars = new char[length];
   8:     for (int i = 0; i < length; i++)
   9:     {
  10:         var index = random.Next(0, funcArray.Length);
  11:         chars[i] = funcArray[index](random);
  12:     }
  13:  
  14:     return new string(chars);
  15: }

Break It Down For Me

Nice, isn't it?  Even if you don't understand Func yet, the code above should be relatively easy on the eyes.  It's not overly long and its brevity implies a certain level of simplicity that welcomes you to come and understand what it's doing rather than scaring you off.  Let's break it down by line by line:

  • I define two Func's, one for generating random numbers and the other for generating random characters (lines 3 and 4).  (This is generating numbers that map to ASCII characters and then casting the number to a char datatype). The Func<Random, char> is the same as "public char(Random r)".  So what I'm saying is, "I'm going to pass you in a Random number generator and you return me back a character, it's up to you whether that character is a letter or number or something else".  If it helps, think of these Func objects as mini-methods.  (Note: I've chosen to pass in the random number generator, you could implement a different way if so desired (what you don't see is that this class has a member variable of type Random)).
  • I then define an array of these Func<Random, char> objects (line 6).  I'll come back to why I am using an array in a moment.
  • I create an array of characters in line 7 to hold the characters that are being generated.
  • Line 8 is a loop defined for the number of characters in the temp password.
  • Line 11 may look a little goofy.  What I'm doing here is allowing passwords to be a bit more random by saying in English, "for however many different ways you can generate a character, randomly pick one".  This has the effect that not only are passwords random, the structure of the generated string is random.  I really like this.
  • Line 12 then is where we leverage the Func.  We take the random index of the func to use from line 10, access a Func at the location in the array we set up in line 6, and execute the function passing in the random number generator.  Take a moment and make sure you understand this line as it is really the heart of the whole method.
  • Line 14 is simply taking the generate characters and returning a string.

Extensibility

Right now I have two Func's defined, one for random characters and another for random numbers.  To change the sequence I could create another Func and simply add it to the array and voila, I've got another character generation option. I only therefore have to touch two lines, the line where the new Func is defined and the line which adds the Func to the array, line 6.  I'm sure there are other ways to add extensibility points, but really how often are you going to want to change your password generation scheme?

Conclusion

If Func seems odd to you make a commitment to use it.  As you use it you'll find that it really isn't that bad and pretty soon you'll be getting down with da Func all the time.


 
Categories: