3

I have to get the maximum throughput performance in my WCF service. In one of my tests the service below got only 50k data items per minute using NetTcpBinding. Would a disconnected binding like NetMsmqBinding improve this performance?

Service and client uses WCF and run in the same machine.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
    ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Storage : IStorage
{
    protected List<int> _data = new List<int>();

    public void Insert(int[] data)
    {
        lock (_data)
        {
            _data.AddRange(data);
        }
    }

    public int[] Get()
    {
        lock (_data)
        {
            return _data.ToArray();
        }
    }
}

The code above is a simplified version of the actual code.

Jader Dias
  • 88,211
  • 155
  • 421
  • 625
  • 2
    Refer to http://stackoverflow.com/questions/1613586/c-wcf-inter-process-communication/1613601#1613601 for a flowchart on how to select WCF bindings. It doesn't directly address the question of performance, but others looking at this question may find it helpful. – Matt Davis Dec 02 '09 at 21:59

4 Answers4

5

Msmq is likely to be slower than TcpBinding.

If you're running on the same machine, you definitely should use NetNamedPipeBinding (IPC) which is the fastest binding available.

You should also check how you're serializing your data. Protocol Buffer serialization is a lot faster (and leaner) than default WCF binary serialization (but requires a little bit of tweaking).

Yann Schwartz
  • 5,954
  • 24
  • 27
  • Yes. That's the one of the two implementations that has pretty good WCF support. I've heard that the creator of that lib is not a total unknown 'round here. – Yann Schwartz Dec 02 '09 at 19:02
  • I used it but it strangely did not improved the performance of my service. – Jader Dias Dec 02 '09 at 19:55
  • How are you testing it ? Do you have many clients or one in a single thread? You may be maxing on CPU usage too. NamedPipeBinding gives the best performance communication-wise, but if you hit a perf wall in your service or client code, you'll have to tackle these too. – Yann Schwartz Dec 03 '09 at 11:57
5

Faster for a single call in isolation, or for a flood of thousands of calls?

NetMsmq uses MSMQ message queueing - you're putting your message into a queue handled by MSMQ, and the service will get it from that queue eventually and work on it. You don't get instant feedback, the messages are one-way only.

NetTcp on the other hand is like http - only faster. You send a request to the service and get back a response (if all goes well) right away. No message queueing per se involved, your messages are request/reply.

So I don't think you can compare the two bindings, really. They serve totally different purposes:

  • if you want to e.g. look up a zip code and get back the longitude/latitude of that location, you definitely want a request/response mechanism --> use netTcp

  • if you want to deposit requests to e.g. print a document, or reorganize a database, or something of that nature - something that needs to be tended to eventually, but you don't expect back a response right away (but you can later check if the message has been handled properly), then use a message queueing system

Hope that makes things a bit clearer - I don't think these two really are geared towards the same set of operations, so you most likely won't ever have to choose between those two directly :)

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • If you look into my code, and if I tell you that each client uses only 1 of the operations (one client Inserts, and another client Gets), I think we will agree that a MSMQ is appropriate to my service. The problem is that I never used it, and I didn't know if it is performant. – Jader Dias Dec 02 '09 at 17:23
  • well - if you want to "GET" something, you'll have to send a "GET" request on the MSMQ to the service. But how do you get the data back?? Since MSMQ is always only one-way........ you almost have to open another (response) queue onto which the service puts the response, and the client needs to go grab the data from there. No, I don't think, MSMQ is a good idea for a GET operation, in general. – marc_s Dec 02 '09 at 17:28
  • So if I understand you well, I would have to ignore this GET method from this service, and transform one of my clients in a service that receives the data, in order to use MSMQ? – Jader Dias Dec 02 '09 at 17:34
3

If the service and client run on the same machine I would avoid the network altogether in favor of an IPC mechanism such as named pipes. Network traffic incurs a lot of overhead which can be avoided by using an IPC mechanism.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
2

Do you have reason to believe that the transport is what is slowing down the transaction rate? What has profiling told you? Right now this service is set to be single threaded, and also has multiple calls to "Get" lock each other out.

How is this service called/used? Would it help to make it multi-threaded? What about using a more sophisticated lock like a ReaderWriterLock which allows multiple calls to Get to occur at the same time, but still block on "Add"?

Edit: I know this is a simplified situation, but would the actual service benifit from the same considerations?

Chris Pitman
  • 12,990
  • 3
  • 41
  • 56