WCF Speed Test using Multiple Endpoints
One of the cool points about Windows Communication Foundation (WCF) is that it lets you change the type of connection you’re using without changing any code. All you need are a few config changes, and hey presto! You can go from HTTP to Named Pipes faster than David Blaine can escape from a lead box full of snakes.
At least that’s the theory. Being so easy to change ‘bindings’ as they’re known in the world of WCF, I thought I’d do a bit of test to see how fast some of the these bindings were. There are many bindings to choose from, but in this case I’ve gone for HTTP (standard protocol for web services – quite verbose, with data transferred as XML), TCP (which is similar to HTTP but has a more compressed, binary data transfer) and Named Pipes (which is normally used for inter-process communication, so should be very efficient).
Using Multiple Endpoints
Although not strictly necessary for this test, one thing I wanted to try was to define a service which had several different bindings at the same time. The idea with this is that you can have a single service, but connect to it in multiple different ways – for example, use Named Pipes to call it from the same machine, TCP from within your own network, or HTTP for anything external. Or maybe you want to offer different SOAP versions for clients of differing advancement. For my test, this means I can have a single service and a single client, and connect using whatever binding I like to do my speed measurements.
So, to begin with, I created my service and added a standard HTTP endpoint along with a MEX endpoint so I could easily create the client from it. (In this case, I’m hosting the service in a simple console app host which I created). I created the client proxy using the ‘Add Service Reference’ functionality in VS2008, got that working, and then set about trying to update the config files to enable different binding types.
As it turns out, this is actually very easy. To enable this at the service end, you simply have to add some endpoints and corresponding base addresses to your config:
You don’t even need to tie them up, or do anything different in your code – to start the host it’s simply:
And bob’s your uncle! Add a bit of a printout on the host to get the service details, we now have the following (notice the three addresses with different ‘Schemes’):
That’s the service sorted – so what about the client? Well, in the normal case of the client connecting to only one service, we’d just need to put the corresponding endpoint details in – but as I want to connect to all three endpoints from the same client, I put all three in:
You might notice here that I’ve stripped the config file down to the bare bones, by removing all of the specific HTTP configuration and the MEX endpoint, just to make things clearer (although this config works fine and is what I used for the test).
In terms of opening the client, again because we’re using multiple endpoints, I’ve had to tell it which one to use by referring to the name I gave the endpoint in the config file:
So I’ve done this for each of the endpoints. Of course, if I’d wanted to be clever I could have read the names from the config file and not had to be so specific in the code – but it’s Sunday, and Top Gear’s on soon.
So that’s it! I now have a service which you can connect to over three different protocols, and a client which can use them all – and David Blaine got out ages ago…
The Speed Test
So onto the speed test. First, I’ll give you a little info about how it was done (although don’t be fooled into thinking this is in any way scientific or tightly controlled).
I created two methods, one passing a simple data type and one a more complex data type:
These methods don’t do anything except pass back the data that was passed in.
Performing the tests was simply a case of calling both of these methods in a loop once, then 10 times, then 100 times each. I also did one ‘warm-up’ call to each method before starting the timing, as WCF services take a little while to get going the first time. This was all done on my local PC, there was no networking involved.
I timed all these calls using a stopwatch, calculated the average, and that’s about all there was to it.
So, you want to know the results? Very well, but I have to give you a number of disclaimers first:
- These results are using a WCF host not IIS, which could make quite a difference
- I haven’t optimised any of the connections (e.g. by putting parameters in the config file)
- The first call was not timed, so if you’re only calling a method once, this won’t mean so much to you
Essentially, this boils down to the standard advice for performance testing – you need to try it yourself, with your particular environment and setup, making the kind of calls you make, to get any meaningful numbers. And with that, here are the meaningless numbers!:
You can see the final averages at the bottom there. Pretty much what you might expect – Named Pipes was slightly faster than TCP, both of which were considerably faster than HTTP.
Of course, it’s all in milliseconds so really not worth paying a lot of attention to, unless you happen to be making hundreds or thousands of calls – and even then, your choice is likely to be made based on security issues, what kind of network you’re using, and the types of client connecting to your service.
So my time’s been pretty much wasted then… Never mind, it’s time for Top Gear now anyway.