DCSIMG
July 2011 - Posts - Offir Shvartz

Offir Shvartz

We code with love or we code not...

July 2011 - Posts

WCF Performance Using Datasets – Part 2

start with reading WCF Performance Using Datasets – Part 1.

Can it be ?

I asked this question over and over – because WCF is clearly faster (see Eyal Vardi comment in part 1). I tried several Binding options including some custom binding , I asked some people to look at my code and up to now no one has manage to contradict my benchmark. I invite each one of you to try (write you own tester) my contract is simple:

[ServiceContract]
 public interface IPerfService
  {
       [OperationContract]
       DataSet LoadDataSet(DataSet ds);
 
  }

Why is WCF slower for Datasets ?

I decided to use a profiler and look at the time consuming deviation. I like using Dot Trace profiler because it is very simple and clear. I was sampling one of 1000 iteration after 100 iteration.

Hold tight we are going deep.

You can see that the WCF call (ClientLoadDataSetSelfHost) took 719 ms and the Web Service call (LoadDataSet) took 619 ms

per1

Drilling down I discovered that this gap was a result in the gap of desterilize method duration – makes sense because this is most of the work (DataSet of 15,000 rows).

it's Important to remember that when serializing / deserializing an object that is implementing IXmlSerializable it doesn't meter what kind of serializer is defined it will use the object IXmlSerializable  implementation – this can be very problematic when using hybrid option when object that not implementing IXmlSerializable  holds members that implements IXmlSerializable but discussing this can write full other post.

Both are using: System.Data.DataSet.ReadXml(XmlReader)   (from System.Xml.Serialization.IXmlSerializable)  - in this function we see the 100 ms diff in duration between Web Service and WCF.

Digging deeper going to the method: System.Data.XmlDataLoader.LoadTable(DataTable, Boolean) called from System.Data.XmlDataLoader.LoadData(XmlReader) called from System.Data.DataSet.ReadXmlDiffgram(XmlReader).

In WCF:

WCFPerf

Web Service:

perfWebService

you can see that most of the method takes more time and this is due to the XMLReader specific type that DataSet is choosing in runtime: in web service XMLTextReader in WCF XMLBinaryReader – reading using BinaryXMLReader is taking more time.

When I used text encoding still in WCF it was using XMLBufferReader and not XMLTextReader. In addition I tried most of the binding options but still DataSet is choosing the XMLBufferReader – I’m open for your suggestions. If we could define specific binding that will get DataSet to behave the same as in WebService it could be very useful. The thing is we cannot modify DataSet Code – the XMLReader specific type choosing part.

What is the solution

I’ll start with what is not the solution for sure which is going back to Web Services – we cannot allow our application not moving to WCF because we need WCF power:Security, full separation of binding from service implementation , easy maintaining , tracing ,error handling and most important this is the technology Microsoft is developing and supporting NOW.

I’ll divide my solution to two main options:

  1. The most correct but annoying solutions: Do not use data set – it’s a large cumbersome out dated object. In addition it’s not strong typed meaning it can cause to fail on runtime. Now the way to go is Domain driven.

I know the fist option is not always possible – sometimes too costly and too risky still this is the way to go.

  1. DataSet Surrogate – I saw it in several places over the web (here is one). This solution is to hold the all dataset data in other fast serialized object and past the surrogate object over the wire. You can change the WCF method signature to pass this SurrageDataSet or better use Parameter Inspectors (read more here) to do it using WCF extensibility options.

Conclusion

You may encounter the situation of passing DataSets in WCF only on legacy solutions but it’s important that when refactoring old application, you should be aware that moving to WCF not necessary means memory improvement – mainly if all your object model is data sets (very common in legacy solutions).

I implemented and tested my own DataSet surrogate (not supporting relations) and in my bench mark WCF was faster then Web Service in ~15%. I’m sure it depends on number of tables and rows and to rebuild DataSet takes time too. Still I think this can bring significant performance improvement.

WCF Performance Using Datasets – Part 1

Background

It’s all started when I encountered a strange behavior in one of the systems I work on.

The system is a legacy system that uses a simple client server architecture implementing using web service – this was pre-WCF time so the options were only .NET remoting and web services. Now as part of major refactoring process of the system we decided to replace the communication layer from WS to WCF.

The motivation is obvious:

  • Alignment with Microsoft latest infrastructure.
  • performance improvement – http to TCP/ Binary encoding.
  • Easy maintenance.
  • Easy monitoring and configuration.
  • Extendible – interception points (behaviors).

After the modification was completed I found that the system became slightly slower  – how can it be.

WCF performance vs. Web Service – What do we know

This bring me to article from 2007 written by Microsoft: http://msdn.microsoft.com/en-us/library/bb310550.aspx

To summarize the results, WCF is 25%—50% faster than ASP.NET Web Services, and approximately 25% faster than .NET Remoting. Comparison with .NET Enterprise Service is load dependant, as in one case WCF is nearly 100% faster but in another scenario it is nearly 25% slower. For WSE 2.0/3.0 implementations, migrating them to WCF will obviously provide the most significant performance gains of almost 4x.”

My Benchmark

Still articles are articles and facts are facts – “the costumer is always right” Smile

In addition in the article there was no mention of datasets specifically.

In the legacy system we mostly use DataSet (I know pretty ugly but this is what we did in a legacy code what can I do…).

So I decided doing my own simple benchmark.

I tested two scenarios:

  1. Pass 10000 objects – the object include two fields: integer and string.
  2. Pass “large” dataset – includes one table the has two string columns contains 10000 rows.

The services types:

  1. Simple ASMX web service.
  2. Self hosted WCF service.

the client makes sequential call to the services: 1 then 2 and I measure the duration in milliseconds.

I repeat the same test 1000 time and use the average duration of the last 100 test runs.

here are the results (duration in milliseconds):

image

image

 

Conducting a Benchmark Notes

Not doing the following can get you faulty results.

  • Remember to run the tests not using Visual Studio (not using the .vshost.exe process).
  • Run the sources complied in “Release”.

Conclusions

My conclusion is for dataset transfer Web Service is faster than WCF (around ~40% faster).

So when choosing to upgrade legacy code to use WCF – will not always increase your system performance – if you use mostly datasets your system may become slower.

What’s next

This is only the start because:

  • First we need to understand what is the cause for the performance decrease – why is WCF slower only for DataSets.
  • Second we need to find a solution to use WCF but still keep our performance or better improve – going back to Web Service is not an option.

So stay tune for part 2, I promise it’s we’ll be worthwhile.

http://blogs.microsoft.co.il/blogs/oshvartz/archive/2011/07/23/wcf-performance-using-datasets-part-2.aspx

Cheers

Offir