Home > WCF > WCF Speed Test using Multiple Endpoints

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:

Specifying multiple endpoints on the service

You don’t even need to tie them up, or do anything different in your code – to start the host it’s simply:

Starting the service host

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’):

Service host details

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:

Client configured for multiple endpoints

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:

Starting the client for a specific endpoint

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:

Service contract used for the speed test

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!:

Speed Test Results

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.

Categories: WCF Tags:
  1. Jesse
    March 16, 2010 at 10:56 am

    I am starting to delve into VS.NET, coming from Delphi. I found your post very interesting and you’ve explained it very clearly. Your meaningless stats were highly informative! I’m sure glad you wasted your time. 🙂

    • relentlessdevelopment
      March 16, 2010 at 1:01 pm

      Glad you found it useful. And good luck with .Net! I think you’ll enjoy it.

  2. Jesse
    March 16, 2010 at 8:29 pm

    I’m convinced a lotta folks are grateful that you were unselfishly willing to share. As I’m a newbie (installed VS 2010 RC just a couple days ago) to .NET, I’m trying to getting up to speed as quick as possible. As I’d like to stand on the shoulder of giants, I’d appreciate it if you’d care to comment on the following. Okay, enough groveling. 🙂 I want to develop a REST web service and a WPF client as a consumer of that web service. I’ve absolutely no idea yet how to accomplish that in VS 2010. Another thing I also found interesting in your post, is that you created a WCF host and did not use IIS. How would one go about that? Not a question that deserves a “lemme google that for ya” reply, I hope. You’ve also said that using a WCF host instead of IIS could make a big difference performance-wise for HTTP. Would you expect using IIS to give better performance because of optimizations by IIS? Sorry, I don’t mean to hassle you but your guru status really shines through your post. So I couldn’t resist asking you for your opinion. TIA.

    • relentlessdevelopment
      March 17, 2010 at 12:57 pm

      I’m afraid you might have to find a much taller giant to stand on for that one, as I haven’t done anything RESTy in WPF at all.. In fact I’m really not much of a guru on the subject, I’m sure you’ll know more about it than me by the end of the day!

      In terms of hosting, if you don’t want to do it in IIS, you can write a simple exe to host your service (which could be a Windows service, console app, or whatever). I don’t have 2010 installed any more (wanted to get rid of it before I got too attached!), but in 2008 the process for that would be something like:
      1. Write your service (WCF Service Library project)
      2. Create an executable to be the host (e.g. Console Application project)
      3. From the host project, reference System.ServiceModel and your service project
      4. Copy the app.config file from your service project to the host project (which includes your service address etc)
      5. In your host, write something like this (where TextService is the name of my service):
      using (ServiceHost serviceHost = new ServiceHost(typeof(TextService)))
      Console.WriteLine(“\nPress to terminate service.”);

      Add a dash of exception handling and bob’s your uncle! Whether you should do this is another matter. While I heard it was faster this way than with IIS, unfortunately it wasn’t part of my test, so I’d take that with a pinch of salt until you get some actual figures.

      A console app as a host is only really useful while you’re in development, for anything serious you’d want to use a Windows Service (if not IIS) – check out this Code Magazine Article for some further info on the hosting options.

      Sorry if that wasn’t a great deal of help, but feel free to get in touch if you have any more (simple!) queries.

      • Jesse
        March 17, 2010 at 3:36 pm

        Thank you for your input. Appreciate it. Whenever I’m over in Leeds visiting my brother-in-law and sister-in-law, I’ll buy a pint of your favorite beer or beverage. Thanks again.

  3. June 17, 2013 at 9:19 am

    Named pipe takes much more time comparatively in “warm-up”(first call). Does this happens each time you run test after some time, or subsequent run test after considerable time returns faster running ?

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: