WCF Binding Performance comparison

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

WCF is definitely powerful  foundation for connecting systems by using various protocols. However many people complains that all around WCF is a bit complicate.
This is true, but we all have to understand that “connecting systems” knowledge requires the truth architecture knowledge of connected systems and of the world between and around them. Because of that most developers just consume WCF at the simples possible way. This is probably in many cases the best way to get something just working.
Unfortunately if you want to get more from WCF, you will need much more time and understanding of all artifacts which most developers likely do not have to consider.This post should help all developers to find out as quick as possible the best possible tuning option for communication. More over it is recommended to all architects to take a look on results presented here.

Following table shows the list of more or less all WCF common bindings (source Aaron post ).

Binding Class Name
Transport
Message Encoding
Message Version
Security Mode
RM
Tx Flow*
BasicHttpBinding
HTTP
Text
SOAP 1.1
None
X
X
WSHttpBinding
HTTP
Text
SOAP 1.2
WS-A 1.0
Message
Disabled
WS-AT
WSDualHttpBinding
HTTP
Text
SOAP 1.2
WS-A 1.0
Message
Enabled
WS-AT
WSFederationHttpBinding
HTTP
Text
SOAP 1.2
WS-A 1.0
Message
Disabled
WS-AT
NetTcpBinding
TCP
Binary
SOAP 1.2
Transport
Disabled
OleTx
NetPeerTcpBinding
P2P
Binary
SOAP 1.2
Transport
X
X
NetNamedPipesBinding
Named Pipes
Binary
SOAP 1.2
Transport
X
OleTx
NetMsmqBinding
MSMQ
Binary
SOAP 1.2
Message
X
X
MsmqIntegrationBinding
MSMQ
X**
X
Transport
X
X
CustomBinding
You decide
You decide
You decide
You decide
You decide
You decide

Depending on what are you going to do the decision of what the binding is the best for you will not be easy. Because this is an obvious issue in the community in context of performance, we (daenet) have decided to prepare lot of measurements for our WCF-Internals session at  Advanced Developer Conference 2011 in Germany. Please also take look on this measurement provided by Microsoft few years ago.
For this performance test we created following WCF contract:

  [ServiceContract()]//SessionMode=SessionMode.Allowed)]

    public interface ISampleService

    {

        [OperationContract]
        int DoWork(string msg);
        

        [OperationContract]
        int PushStream(Stream msg);
 

        [OperationContract]
        int PutData(string msg, byte[] data);
    }

 
We also have implemented the service for this contract. Please see comments to understand what is the purpose of what operation.

public class SampleService : ISampleService

    {

        /// <summary>

        /// Invoked by all tests instead of streaming and MTOM.

        /// </summary>

        /// <param name="msg"></param>

        /// <returns></returns>

        public int DoWork(string msg)

        {

            return new Random().Next(int.MaxValue);

        }

 

 

        /// <summary>

        /// Invoked by streaming test (StreamOverHttp).

        /// </summary>

        /// <param name="msg"></param>

        /// <returns></returns>

        public int PushStream(Stream msg)

        {

            return new Random().Next(int.MaxValue);

        }

 

        /// <summary>

        /// Invoked by MTOM test only.

        /// </summary>

        /// <param name="msg"></param>

        /// <param name="data"></param>

        /// <returns></returns>

        public int PutData(string msg, byte[] data)

        {

            return new Random().Next(int.MaxValue);

        }

    }


Then we installed the service on IIS with HTTP and TCP enabled protocols:

     <endpoint address="basic" binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="PerformanceSamples.ISampleService" />

 

        <endpoint address="basicStreamed" binding="basicHttpBinding" bindingConfiguration="basicStreamedBinding" contract="PerformanceSamples.ISampleService" />
 

        <endpoint address="mtom" binding="basicHttpBinding" bindingConfiguration="basicMtomBinding" contract="PerformanceSamples.ISampleService" />

       

        <endpoint address="tcp" binding="netTcpBinding" bindingConfiguration="tcpNoSessionBinding" contract="PerformanceSamples.ISampleService">
        </endpoint>

 

        <endpoint address="tcpSession" binding="netTcpBinding" bindingConfiguration="tcpSessionBinding" contract="PerformanceSamples.ISampleService"/>

 

        <endpoint address="tcpNoAnything" binding="netTcpBinding" bindingConfiguration="tcpBinding" contract="PerformanceSamples.ISampleService"/>

 


Bindings for shown endpoints look like shown in following table. You do not have to read all details here. They are here if you want to know how exactly we have configured specific bindings.

 <basicHttpBinding>

       

        <binding name="basicBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"

                 maxBufferSize="2147483647"  maxBufferPoolSize="1" maxReceivedMessageSize="2147483647"

                 messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">

          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

        

          <security mode="None">

           

          </security>

        </binding>

 

        <binding name="basicStreamedBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:11:00" allowCookies="false" bypassProxyOnLocal="false"

                 hostNameComparisonMode="StrongWildcard"

                 maxBufferSize="65535" maxBufferPoolSize="65535" maxReceivedMessageSize="2147483647"

                 messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed" useDefaultWebProxy="true">

         

          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

 

          <security mode="None">

 

          </security>

        </binding>

 

 

        <binding name="basicMtomBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:11:00" allowCookies="false" bypassProxyOnLocal="false"

               hostNameComparisonMode="StrongWildcard"

               maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"

               messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed" useDefaultWebProxy="true">

 

          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

 

          <security mode="None">

 

          </security>

        </binding>

      </basicHttpBinding>

 

      <netTcpBinding>

        <binding name="tcpNoSessionBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false"

                 transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="6553600"

                 maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647">

          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="16384" />

          <reliableSession enabled="false" />

          <security mode="Message"></security>

        </binding>

 

        <binding name="tcpSessionBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"

                 transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard"

                 listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647">

          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384" maxBytesPerRead="2147483647" maxNameTableCharCount="16384" />

          <reliableSession enabled="true" />

          <security mode="Message"></security>

        </binding>

 

 

        <binding name="tcpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"

                 transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard"

                 listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647">

          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384" maxBytesPerRead="2147483647" maxNameTableCharCount="16384" />

          <reliableSession enabled="false" />

          <security mode="None"></security>

        </binding>

       

       

      </netTcpBinding>


Then we have implemented tests which invoke named service operations by sending of messages of different size like: 10kb, 100kb, 600kb, 6MB, 17MB, 20MB and 40MB. Then we have grouped test in two groups. First group of tests uses operation DoWork(string) . Second group of tests is related to sending of binary array and stream. 

First group covers following scenarios:
  • Simple Http text message Transfer. (test name: Basic Unencrypted – No credentials)
  • Simple Tcp text message transfer (test name: NetTcp No Reliable session – no credentials)
  • Http text message transfer with enabled message security. (Test name:WsHttp No reliable session – Msg security)
  • Tcp  text message transfer with enabled message security.(Test name: NetTcp no reliable session – Msg security)
  • Http message transfer with message security and enabled reliable session.(Test name: WsHttpNo reliable Session - Msg Security)
  • Http message transfer enabled message security and disabled reliable session. (Test name: reliable Session - Msg Security)
  • Http basic binding with enabled streming (Test name: BasicStreamed).

All these tests invoke same operation:

[OperationContract]
int DoWork(string msg); Second group covers following scenarios (of course no encryption digital signature and session):

  • Sending of a binary array. (Test name: Testname: Mtom_Test)
  • Streaming of data via streamed contract (StreamedOverHttp_Test)

Go to Part II


Posted Oct 21 2011, 09:24 AM by Damir Dobric
Filed under:

Comments

Damir Dobric Posts wrote WCF Binding Performance comparison–Part 2
on 10-26-2011 1:29

In the previous post I have described group of WCF performance binding test which we did. This post contains

DamirDobric wrote WCF Binding Performance comparison–Part 2
on 10-26-2011 2:39

In the previous post I have described group of WCF performance binding test which we did. This post contains

WCF Binding Performance comparison???Part 2 - Damir Dobric Posts - developers.de wrote WCF Binding Performance comparison???Part 2 - Damir Dobric Posts - developers.de
on 10-26-2011 10:28

Pingback from  WCF Binding Performance comparison???Part 2 - Damir Dobric Posts - developers.de

developers.de is a .Net Community Blog powered by daenet GmbH.