views:

469

answers:

4

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.

+3  A: 

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
+1 for the named pipes. Shame WCF 4.0 had to drop localProcessBinding too :(
MattC
+3  A: 

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
http://code.google.com/p/protobuf-net/wiki/Performance
Jader Dias
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
I used it but it strangely did not improved the performance of my service.
Jader Dias
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
+2  A: 

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
+1 for raising the issue
Yann Schwartz
I just corrected the ConcurrencyMode. Thanks!
Jader Dias
Yes, I think the actual service would benefit from an advanced lock too.
Jader Dias
+3  A: 

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