title: Does protobuf-net have built-in compression for serialization?
body: <p>I was doing some comparison between <code>BinaryFormatter</code> and protobuf-net serializer and was quite pleased with what I <a href="http://theburningmonk.com/2011/08/performance-test-binaryformatter-vs-protobuf-net/" rel="noreferrer">found</a>, but what was strange is that protobuf-net managed to serialize the objects into a smaller byte array than what I would get if I just wrote the value of every property into an array of bytes without any metadata.</p>
  
  <p>I know protobuf-net supports string interning if you set <code>AsReference</code> to <code>true</code>, but I'm not doing that in this case, so does protobuf-net provide some compression by default?</p>
  
  
  
  <p>Here's some code you can run to see for yourself:</p>
  
  <pre class="lang-cs prettyprint-override"><code>var simpleObject = new SimpleObject
                         {
                             Id = 10,
                             Name = "Yan",
                             Address = "Planet Earth",
                             Scores = Enumerable.Range(1, 10).ToList()
                         };
  
  using (var memStream = new MemoryStream())
  {
      var binaryWriter = new BinaryWriter(memStream);
      // 4 bytes for int
      binaryWriter.Write(simpleObject.Id);      
      // 3 bytes + 1 more for string termination
      binaryWriter.Write(simpleObject.Name);    
      // 12  bytes + 1 more for string termination
      binaryWriter.Write(simpleObject.Address); 
      // 40 bytes for 10 ints
      simpleObject.Scores.ForEach(binaryWriter.Write); 
  
      // 61 bytes, which is what I expect
      Console.WriteLine("BinaryWriter wrote [{0}] bytes",
        memStream.ToArray().Count());
  }
  
  using (var memStream = new MemoryStream())
  {
      ProtoBuf.Serializer.Serialize(memStream, simpleObject);
  
      // 41 bytes!
      Console.WriteLine("Protobuf serialize wrote [{0}] bytes",
        memStream.ToArray().Count());
  }
  </code></pre>
  
  <p>EDIT: forgot to add, the <code>SimpleObject</code> class looks like this:</p>
  
  <pre class="lang-cs prettyprint-override"><code>[Serializable]
  [DataContract]
  public class SimpleObject
  {
      [DataMember(Order = 1)]
      public int Id { get; set; }
  
      [DataMember(Order = 2)]
      public string Name { get; set; }
  
      [DataMember(Order = 3)]
      public string Address { get; set; }
  
      [DataMember(Order = 4)]
      public List&lt;int&gt; Scores { get; set; }
  }
  </code></pre>