rickgaribay.net

Space shuttles aren't built for rocket scientists, they're built for astronauts. The goal isn't the ship, its the moon.
posts - 299, comments - 169, trackbacks - 33

My Links

News

Archives

Post Categories

Published Works

Comparing WCF Binary Encoding to .NET Serialization

A common question that I get from folks at my talks as well as clients is how binary performance of WCF stacks up against .NET Remoting. To quickly level-set, the lingua franca for all messages that WCF exchanges is SOAP/XML. However, out of the box, WCF provides 3 means for representing the message payload on the wire:

  • Binary
  • Text
  • MTOM

Of the encodings above, only Text and MTOM are interoperable (and I'll cover these in upcoming posts), but sometimes, in a .NET to .NET messaging scenario, encoding the message in a binary representation will yield smaller payloads and thus more efficient message transfer (especially when pairing a binary message with TCP). It is important to note that regardless of the encoding used to serialize the message, the message itself is SOAP and thus can be de-serialized according to the SOAP standard in use on the client and server stack.

It is widely documented that the System.Runtime.Serialization assembly introduces an optimized byte representation for packaging XML/SOAP via the XmlDictonaryWriter which can be found in the System.Xml namespace within the System.Runtime.Serialization.dll.

In short, WCF leverages the XmlDictionaryWriter which provides a factory method for getting a binary writer which is capable of taking an XML document and serializing it to a proprietary binary format:

XmlDocument doc = new XmlDocument(); 
doc.Load(from); 

FileStream stream = new FileStream(to, FileMode.OpenOrCreate); 

XmlDictionaryWriter binaryWriter = XmlDictionaryWriter.CreateBinaryWriter(stream); 
doc.WriteContentTo(binaryWriter); 

binaryWriter.Flush();

The code above takes a file containing the following XML and loads it into an instance of the XmlDocument:

image

Then, using the binary encoder, the stream is written to a file called "CustomerWCF.bin" on disk, which when opened looks like this:

image

Similarly, if I want to use the "legacy" BinaryFormatter, which ships in the System.Runtime.Serialization.Formatters namespace of mscorlib, I can write the following code which loads and serializes the same Customer.xml file:

XmlDocument doc = new XmlDocument(); 
doc.Load(from); 

FileStream stream = new FileStream(to, FileMode.OpenOrCreate); 

BinaryFormatter formatter = new BinaryFormatter(); 
formatter.Serialize(stream, doc.InnerXml);

 

This time, the contents is written to a file called CustomerNET.bin which resembles the following:

image

Of course, both of these files are encoded in binary, so when you open them in notepad or some other tool (in this case I am using Visual Studio) you will see some semblance of the original message with corresponding octal representation for each byte of data. It is evident, in just looking at the octal representation that the CustomerNET.bin is larger.

In fact, it turns out that the CustomerWCF.bin file has a size of 98 bytes, compared to the CustomerNET.bin file that has a size of 205 bytes.

Customer.WCF.bin:

image

CustomerNET.bin:

image

Given this very simple example, you could say that the WCF binary encoder produces a payload that is roughly half the size of the BinaryFormatter!

It is important to note that the these are different binary representations, that are each proprietary and therefore not interoperable outside of the .NET Framework. In fact, the WCF version of the Customer.xml contents is only supported within .NET 3.0 and later, and is naturally the encoder that is used when exchanging binary messages with WCF. The cool thing is that you can leverage this encoding outside of WCF, provided you have .NET 3.0+ on both sides of the wire.

Forthcoming: Exploring Text and MTOM message representations.

Print | posted on Friday, September 19, 2008 7:42 AM | Filed Under [ WCF .NET 3.5 ]

Feedback

Gravatar

# re: Comparing WCF Binary Encoding to .NET Serialization

Very interesting artical. so, how do i make sure my client server application is using binary encoding and not xml serialization?
i have a client server app which both are running wcf in .net 3.5.

thanks!
10/29/2008 12:17 PM | Michael Furibondo
Gravatar

# re: Comparing WCF Binary Encoding to .NET Serialization

You will need to add the [XmlSerializerFormat] attribute.

So (without using Datacontract although you can use that too):

[ServiceContract(Namespace = "urn:SerializationTest")]

[XmlSerializerFormat]

public interface IBlah

{

[OperationContract]

XmlDocument Returnxmldoc();

}
12/18/2008 3:46 AM | Harsh Pandit
Gravatar

# re: Comparing WCF Binary Encoding to .NET Serialization

Harsh, not sure I follow you. I believe Michael's question is how to enable binary encoding instead of text. To do so, you can simply set the encoding property/attribute of the given binding.

This example from MSDN shows you how to manage multiple knobs and switches on the binding, including setting encoding to text (XML):

BasicHttpBinding binding = new BasicHttpBinding();

BasicHttpBinding transportSecurityBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);

EnvelopeVersion envelopeVersion = binding.EnvelopeVersion;
//Output of TxtEV to TextBlock: Soap11 (http://schemas.xmlsoap.org/soap/evelope/)
string TxtEV = envelopeVersion.ToString();

// Get default MaxBufferSize
int maxBufferSize = binding.MaxBufferSize;
//Output of txtMBS to TextBlock: 65536
string txtMBS = maxBufferSize.ToString();

// Set new MaxBufferSize
binding.MaxReceivedMessageSize = 4096;
string txtNewMBS = binding.MaxReceivedMessageSize.ToString();


// Get default MaxReceivedMessageSize
long maxReceivedBufferSize = binding.MaxReceivedMessageSize;
//Output of txtMBS: 65536
string txtMRBS = maxReceivedBufferSize.ToString();

// Set new MaxReceivedMessageSize
binding.MaxReceivedMessageSize = 4096;
string txtNewMRBS = binding.MaxReceivedMessageSize.ToString();


// Get Scheme value
// Output of txtScheme: http
string txtScheme = binding.Scheme;



BasicHttpBinding bDefaultHttpBinding = new BasicHttpBinding();
//Output txtSecurityMode: None
string txtDefaultSecurityMode = bDefaultHttpBinding.Security.Mode.ToString();

BasicHttpBinding bTHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
//Output txtSecurityMode: Transport
string txtTSecurityMode = bTHttpBinding.Security.Mode.ToString();

BasicHttpBinding bTOHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
//Output txtSecurityMode: TransportCredentialOnly
string txtTOSecurityMode = bTOHttpBinding.Security.Mode.ToString();



//Gets the character encoding for the binding
Encoding encoding = binding.TextEncoding;
//Output txtEncoding: System.Text.UTF8Encoding
string txtEncoding = encoding.ToString();
Encoding unicodeEncoding = new UnicodeEncoding();
//Set a Unicode encoding for the binding
binding.TextEncoding = unicodeEncoding;
//Output txtEncoding: System.Text.UnicodeEncoding
string txtUEncoding = binding.TextEncoding.ToString();



BasicHttpBinding basicEHBinding = new BasicHttpBinding();
BindingElementCollection bindingEC = basicEHBinding.CreateBindingElements();
//Check on binding elements contained in the collection
bool boolHTBE = bindingEC.Contains(typeof(HttpTransportBindingElement));
//Returns true
string txtboolHTBE = boolHTBE.ToString();
bool boolHSTBE = bindingEC.Contains(typeof(HttpsTransportBindingElement));
//Returns false
string txtboolHSTBE = boolHSTBE.ToString();
12/18/2008 8:27 AM | Rick
Gravatar

# re: Comparing WCF Binary Encoding to .NET Serialization

Your comparison is of little practical interest!

One would NEVER use binary serialization of an XML representation of an object's state with .NET remoting.
Instead, one would serialize an object's state to a binary format directly, using marshal by value objects.
And that is a scenario where remoting is blazingly faster and more compact than WCF, no matter what Microsoft claims!

Consequently, you should use .net remoting where performance matters (e.g. when implementing a heavy duty application server), and WCF where interoperability with other platforms matters.
8/6/2009 11:33 AM | Strider
Comments have been closed on this topic.

Powered by: