Developer's Diary

Thoughts on innovations in the software development field, with focus on the Microsoft platform. C#, C++, .NET Framework, client and server products.

Wednesday, September 13, 2006

Code statistics and documentation

Code statistics
I would like to recommend an add-in for Visual Studio that I have been using for many years now, called Project Line Counter. It is a code statistics add-on for Visual Studio, from version 6.0 and up. I use this to measure relative complexity between my projects, counting lines of code, comments, blank lines, etc.

Code documentation
Code layout and documentation (proper commenting) is something that is very important to me. There is something beautiful lingering over a well crafted piece of code that has been carefully commented. The art of writing code that is more or less self-explanatory intrigues me. Back in the days when C++ was my everyday language, I used a well known tool called Doxygen. I have long kept my eye out for a good replacement when working on the C# platform.

There is the NDoc utility, which, when I tried it out, didn't have any support for .NET Framework 2.0, and specifically generics. At the same time, I found that Microsoft Sandcastle - Microsoft's MSDN-style code documentation generation tool - had been released as a CTP, so I decided to have a look. Unfortunately, the CTP I tested was very cumbersome to use, with very illogical hardcoded paths, many steps that needed to be performed manually, etc. After some experimenting and a couple of .bat files, I did manage to produce a CHM style documentation for my test project. At first, I had problems getting it to resolve the .NET Framework types, but I managed to get this working.
There is now a later release - the August CTP - and without having tested it, I hope it's easier to use.

All in all, I would recommend people to at least have a look at it. Good documentation generation tools for C# doesn't come in bundles, but I find them very necessary. More people should use them. Currently, it's basically a battle between NDoc and Sandcastle, where NDoc has the lead. I have read that Sandcastle will be integrated with Visual Studio, which sounds great for me. I will definitely continue to follow that up.

Labels:

Monday, September 11, 2006

Juicing up your WCF services

This weekend has been so relaxed that I'm almost ashamed of it. However, I think I needed some quality do-nothing-at-all time, because I did start to feel tiny stress symptoms at the end of last week. Positive stress resulting in negative effects, I suppose. Feel back on track now. The swedish election is coming up, and I must say I find the debate shows on TV quite amusing; more so than earlier years.

However relaxed my weekend has been, the occasional debates and sushi eating aside, I did get quite a bit of time to play around with WCF. I couldn't resist that opportunity, could I?

Optimizing service events
I started delving into the wonderful world of duplex services, and thus, service callbacks. There is a lot to be explored here, and I have merely tapped into the very surface. Duplex services in WCF can be implemented using non-duplex protocols, such as HTTP. WCF does this by adding extra information to the SOAP header, for example by using the WS-Reliable Messaging specification and operating the service as a Composite Duplex (which essentially means combining two separate channels into one). There is a big drawback to using HTTP, though: services must use the wsDualHttpBinding binding, which is very slow. The wsDualHttpBinding binding is the only one of the HTTP bindings that support duplex services. So what can be done?

The answer is to use the netTcpBinding binding. TCP is by design a duplex protocol and is, as I explored in my last blog entry, very fast. With a TCP-based service, the callback performance does indeed improve drastically.

Just for fun, I decided to declare a customBinding binding and see if I could make the callbacks work that way as well. I started out with a custom binding that implemented the following channel stack, in order, top down:
  • reliableSession
  • textMessageEncoding
  • tcpTransport
This worked like a charm - I still got my callback messages. I removed the reliableSession channel, and it still worked. I also noted a side effect, something that had been bothering me before. Service startup times were drastically shorter than that of any other pre-packaged binding I had tested, it even surpassed the netTcpBinding.

Optimizing service startup
As it turns out, when a service that implements the netTcpBinding starts up, it performs 44 DLL loads. The service implementing the customBinding performs 25 DLL loads. The interesting differences being one or more loads of:
  • System.DirectoryServices.ni.dll
  • ntdsapi.dll
  • DNSAPI.dll
  • Secur32.dll
This hints that it might be the security features of the netTcpBinding binding that takes up the extra load time, but I am yet to confirm this. Load times were over 1 second for the netTcpBinding service; the customBinding service was roughly 10 times faster, so quite a big difference.

I can't quite grasp these scenarios yet, but I think I'm fairly close to figuring out the cause and will get back to that in a later post. Cheers!

Labels:

Friday, September 08, 2006

.NET Framework 3.0 and performance

I would like to welcome any new readers (which would be everyone, since this is my first post) to this attempt of mine to document my findings in the software development field. My big swedish fan base may be disappointed in the fact that I have decided to publish this thing in english, but I really would like to share information with all nationalities.

I've been getting my hands dirty with the new .NET Framework 3.0, and more specifically, the Windows Communication Foundation part. Up until a week ago, I had been using the June CTP, since this was the latest version with a set of functioning add-ons for Visual Studio 2005. On September 1st, Microsoft released the .NET Framework 3.0 RC1. The RC1 doesn't hold many new features compared to the July CTP, but instead focuses on increased performance and stability. I was curious to see what the differences were, if any.

Experiences and impressions
Let me first tell you that I am very impressed with how the WCF architecture is constructed. It is very versitile, designed to be the new communication architecture for many years to come, with its own customizable channel stack at heart. And yet, it is extremely simple to work with. Let me enumerate a few of the things I found very useful:
  • Ability to host services in any executable, be it the IIS, a windows service or a console application
  • Very flexible and extendable architecture
  • Enabling use of other protocols than HTTP, such as raw TCP or Named Pipes
  • Services configurable through web.config/app.config, so for instance changing the network protocol does not require a recompilation
  • Support for using multiple endpoints and different protocols at the same time
If you need a crash course in WCF, this article does a pretty good job.

RC1 performance
I have experimented with performance and found that RC1 is definitely a bit faster than the older June CTP. This is most visible when making HTTP calls, since these include more overhead and thus take more time generally than, for instance, TCP. Where a call would take 250 ms with the June CTP, I was now down to around 200 ms with the RC1. Similarly, TCP calls were generally around 10-11 ms with the June CTP, while the RC1 pushed them down to the 7 ms neighbourhood. With named pipes, I got down to 5 ms. These tests were all run with empty method bodies - to get the pure response times, built in release mode and running as a windows service on a virtual machine. I'm sure you would get even better performance on a physical machine. Enabling basic security settings unfortunately impedes performance drastically.

Think about it... 7 ms for a web service call is not much. The traditional web service HTTP call would take 30 times longer. So what does this imply?

You could design your services so that they communicate with other services on the same LAN using TCP calls, while HTTP endpoints would be exposed for consuming applications, internal or external. Technically, the only thing that has changed when using TCP instead of HTTP is just that, the transport protocol. The payload is still the same, following the same WS-* and SOAP standards, so compatibility shouldn't be a big factor. You might still want to expose a HTTP endpoint simply because most implementations assume that web services are run through a web server, and thus HTTP. I see great potential to write more efficient service oriented code here.

Labels: