public static void WriteTo(
                IObjectWriter writer,
                ProtoBufNetTestObject obj)
            {
                if (null == obj)
                {
                    writer.WriteNullValue();
                    return;
                }

                writer.WriteStartObject();

                writer.WriteStartMember(1);
                writer.WriteValue(obj.Foo);
                writer.WriteEndMember();

                writer.WriteStartMember(2);
                writer.WriteValue(obj.Bar);
                writer.WriteEndMember();

                writer.WriteStartMember(3);
                writer.WriteValue(obj.Blip);
                writer.WriteEndMember();

                writer.WriteStartMember(4);
                writer.WriteValue(obj.Blop);
                writer.WriteEndMember();

                writer.WriteEndObject();
            }
            public static ProtoBufNetTestObject ReadFrom(
                IObjectReader reader)
            {
                ProtoBufNetTestObject obj = null;

                if (reader.ReadStartObject())
                {
                    obj = new ProtoBufNetTestObject();

                    int memberKey;

                    while (reader.ReadNextMemberKey())
                    {
                        memberKey = reader.MemberKey;

                        if (memberKey == 1)
                        {
                            obj.Foo = reader.ReadValueAsInt32();
                        }
                        else if (memberKey == 2)
                        {
                            obj.Bar = reader.ReadValueAsString(StringQuotaInBytes);
                        }
                        else if (memberKey == 3)
                        {
                            obj.Blip = reader.ReadValueAsSingle();
                        }
                        else if (memberKey == 4)
                        {
                            obj.Blop = reader.ReadValueAsDouble();
                        }
                    }

                    reader.ReadEndObject();
                }

                return obj;
            }
        public void ProtoBufNetTest()
        {
            const int WarmupIterations = 10;
            const int Iterations = 1000000;

            Stopwatch writeStopWatch = new Stopwatch();

            byte[] buffer = new byte[128 * 1024];
            byte[] serialized;

            ProtoBufNetTestObject writeObject = new ProtoBufNetTestObject()
            {
                Foo = 12,         // 01-01-0C
                Bar = "bar",      // 02-03-62-61-72
                Blip = 123.45f,   // 03-04-42-F6-E6-66
                Blop = 123.4567f, // 04-08-40-5E-DD-3A-A0-00-00-00
            };

            ObjectReaderWriterFactory factory = new PortableBinaryObjectReaderWriterFactory();

            // Serialize the test object to a byte array
            using (var stream = new MemoryStream(buffer))
            {
                IObjectWriter writer;

                GC.Collect(3, GCCollectionMode.Forced, true);

                // Warm-up
                for (int i = 0; i < WarmupIterations; i += 1)
                {
                    stream.SetLength(0);
                    writer = factory.CreateWriter(stream);
                    ProtoBufNetTestObject.WriteTo(writer, writeObject);
                }

                writer = factory.CreateWriter(Stream.Null);

                writeStopWatch.Start();

                for (int i = 0; i < Iterations; i += 1)
                {
                    ProtoBufNetTestObject.WriteTo(writer, writeObject);
                }

                writeStopWatch.Stop();

                serialized = stream.ToArray();
            }

            string writeDump = serialized.ToAsciiDumpString();
            Debug.WriteLine(writeDump);

            Test.Output("{0} writer serialized {1} simple objects ({2:#,###} bytes each) in {3} ms ({4} ticks @ {5}). Average is {6} ticks per object.",
                factory.Name, Iterations, serialized.Length, writeStopWatch.Elapsed.TotalMilliseconds, writeStopWatch.ElapsedTicks, Stopwatch.Frequency, writeStopWatch.ElapsedTicks / Iterations);

            Stopwatch readStopWatch = new Stopwatch();

            ProtoBufNetTestObject readObject = null;

            // Deserialize the test object from a byte array
            using (var stream = new MemoryStream(serialized))
            {
                IObjectReader reader;

                // Warm-up
                for (int i = 0; i < WarmupIterations; i += 1)
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    reader = factory.CreateReader(stream);
                    readObject = ProtoBufNetTestObject.ReadFrom(reader);
                }

                readStopWatch.Start();

                for (int i = 0; i < Iterations; i += 1)
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    reader = factory.CreateReader(stream);
                    readObject = ProtoBufNetTestObject.ReadFrom(reader);
                }

                readStopWatch.Stop();
            }

            Test.Output("{0} reader deserialized {1} simple objects ({2:#,###} bytes each) in {3} ms ({4} ticks @ {5}). Average is {6} ticks per object.",
                factory.Name, Iterations, serialized.Length, readStopWatch.Elapsed.TotalMilliseconds, readStopWatch.ElapsedTicks, Stopwatch.Frequency, readStopWatch.ElapsedTicks / Iterations);

            // Compare objects
            writeObject.VerifyIsEqual(readObject);
        }
            public void VerifyIsEqual(
                ProtoBufNetTestObject other)
            {
                if (this.Foo != other.Foo)
                {
                    throw new Exception("Foo does not match.");
                }

                if (this.Bar != other.Bar)
                {
                    throw new Exception("Bar does not match.");
                }

                if (this.Blip != other.Blip)
                {
                    throw new Exception("Blip does not match.");
                }

                if (this.Blop != other.Blop)
                {
                    throw new Exception("Blop does not match.");
                }
            }