Skip to content

Instantly share code, notes, and snippets.

@neuecc
Created October 26, 2016 06:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neuecc/52a5e0e07e25b52eead26f93ad2b52f9 to your computer and use it in GitHub Desktop.
Save neuecc/52a5e0e07e25b52eead26f93ad2b52f9 to your computer and use it in GitHub Desktop.
// Install-Package MsgPack.Cli
// Install-Package Newtonsoft.Json
// Install-Package protobuf-net
// Install-Package ZeroFormatter
using MsgPack.Serialization;
using Newtonsoft.Json;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using ZeroFormatter;
[ZeroFormattable]
[Serializable]
[ProtoContract]
public class Person
{
[Index(0)]
[MessagePackMember(0)]
[ProtoMember(1)]
public virtual int Age { get; set; }
[Index(1)]
[MessagePackMember(1)]
[ProtoMember(2)]
public virtual string FirstName { get; set; }
[Index(2)]
[MessagePackMember(2)]
[ProtoMember(3)]
public virtual string LastName { get; set; }
[Index(3)]
[MessagePackMember(3)]
[ProtoMember(4)]
public virtual Sex Sex { get; set; }
}
public enum Sex
{
Unknown, Male, Female,
}
class Program
{
const int Iteration = 10000;
static bool dryRun = true;
static void Main(string[] args)
{
var p = new Person
{
Age = 99,
FirstName = "hoge",
LastName = "huga",
Sex = Sex.Male,
};
IList<Person> l = Enumerable.Range(1, 1000).Select(x => new Person { Age = x, FirstName = "a", LastName = "b", Sex = Sex.Female }).ToArray();
Console.WriteLine("Warming-up");
SerializeZeroFormatter(p); SerializeZeroFormatter(l);
SerializeProtobuf(p); SerializeProtobuf(l);
SerializeMsgPack(p); SerializeMsgPack(l);
SerializeJsonNet(p); SerializeJsonNet(l);
dryRun = false;
Console.WriteLine();
Console.WriteLine("Small Object"); Console.WriteLine();
var a = SerializeZeroFormatter(p); Console.WriteLine();
var b = SerializeProtobuf(p); Console.WriteLine();
var c = SerializeMsgPack(p); Console.WriteLine();
var d = SerializeJsonNet(p); Console.WriteLine();
Console.WriteLine("Large Array"); Console.WriteLine();
var e = SerializeZeroFormatter(l); Console.WriteLine();
var f = SerializeProtobuf(l); Console.WriteLine();
var g = SerializeMsgPack(l); Console.WriteLine();
var h = SerializeJsonNet(l); Console.WriteLine();
}
static T SerializeZeroFormatter<T>(T original)
{
Console.WriteLine("ZeroFormatter");
T copy = default(T);
byte[] bytes = null;
using (new Measure("Serialize"))
{
for (int i = 0; i < Iteration; i++)
{
bytes = ZeroFormatterSerializer.Serialize(original);
}
}
using (new Measure("Deserialize"))
{
for (int i = 0; i < Iteration; i++)
{
copy = ZeroFormatterSerializer.Deserialize<T>(bytes);
}
}
using (new Measure("ReSerialize"))
{
for (int i = 0; i < Iteration; i++)
{
bytes = ZeroFormatterSerializer.Serialize(copy);
}
}
if (!dryRun)
{
Console.WriteLine(string.Format("{0,15} {1}", "Size of Binary", ToHumanReadableSize(bytes.Length)));
}
return copy;
}
static T SerializeProtobuf<T>(T original)
{
Console.WriteLine("protobuf-net");
T copy = default(T);
MemoryStream stream = null;
using (new Measure("Serialize"))
{
for (int i = 0; i < Iteration; i++)
{
ProtoBuf.Serializer.Serialize<T>(stream = new MemoryStream(), original);
}
}
using (new Measure("Deserialize"))
{
for (int i = 0; i < Iteration; i++)
{
stream.Position = 0;
copy = ProtoBuf.Serializer.Deserialize<T>(stream);
}
}
using (new Measure("ReSerialize"))
{
for (int i = 0; i < Iteration; i++)
{
ProtoBuf.Serializer.Serialize<T>(stream = new MemoryStream(), copy);
}
}
if (!dryRun)
{
Console.WriteLine(string.Format("{0,15} {1}", "Size of Binary", ToHumanReadableSize(stream.Position)));
}
return copy;
}
static T SerializeMsgPack<T>(T original)
{
Console.WriteLine("MsgPack-CLI");
T copy = default(T);
byte[] bytes = null;
using (new Measure("Serialize"))
{
for (int i = 0; i < Iteration; i++)
{
bytes = MessagePackSerializer.Get<T>().PackSingleObject(original);
}
}
using (new Measure("Deserialize"))
{
for (int i = 0; i < Iteration; i++)
{
copy = MessagePackSerializer.Get<T>().UnpackSingleObject(bytes);
}
}
using (new Measure("ReSerialize"))
{
for (int i = 0; i < Iteration; i++)
{
bytes = MessagePackSerializer.Get<T>().PackSingleObject(copy);
}
}
return copy;
}
static T SerializeJsonNet<T>(T original)
{
Console.WriteLine("JSON.NET");
var jsonSerializer = new JsonSerializer();
T copy = default(T);
MemoryStream stream = null;
using (new Measure("Serialize"))
{
for (int i = 0; i < Iteration; i++)
{
stream = new MemoryStream();
using (var tw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
using (var jw = new JsonTextWriter(tw))
{
jsonSerializer.Serialize(jw, original);
}
}
}
using (new Measure("Deserialize"))
{
for (int i = 0; i < Iteration; i++)
{
stream.Position = 0;
using (var tr = new StreamReader(stream, Encoding.UTF8, false, 1024, true))
using (var jr = new JsonTextReader(tr))
{
copy = jsonSerializer.Deserialize<T>(jr);
}
}
}
using (new Measure("ReSerialize"))
{
for (int i = 0; i < Iteration; i++)
{
stream = new MemoryStream();
using (var tw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
using (var jw = new JsonTextWriter(tw))
{
jsonSerializer.Serialize(jw, copy);
}
}
}
if (!dryRun)
{
Console.WriteLine(string.Format("{0,15} {1}", "Size of Binary", ToHumanReadableSize(stream.Position)));
}
return copy;
}
struct Measure : IDisposable
{
string label;
Stopwatch s;
public Measure(string label)
{
this.label = label;
this.s = Stopwatch.StartNew();
}
public void Dispose()
{
s.Stop();
if (!dryRun)
{
Console.WriteLine($"{ label,15} {s.Elapsed.TotalMilliseconds} ms");
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
static string ToHumanReadableSize(long size)
{
return ToHumanReadableSize(new Nullable<long>(size));
}
static string ToHumanReadableSize(long? size)
{
if (size == null) return "NULL";
double bytes = size.Value;
if (bytes <= 1024) return bytes.ToString("f2") + " B";
bytes = bytes / 1024;
if (bytes <= 1024) return bytes.ToString("f2") + " KB";
bytes = bytes / 1024;
if (bytes <= 1024) return bytes.ToString("f2") + " MB";
bytes = bytes / 1024;
if (bytes <= 1024) return bytes.ToString("f2") + " GB";
bytes = bytes / 1024;
if (bytes <= 1024) return bytes.ToString("f2") + " TB";
bytes = bytes / 1024;
if (bytes <= 1024) return bytes.ToString("f2") + " PB";
bytes = bytes / 1024;
if (bytes <= 1024) return bytes.ToString("f2") + " EB";
bytes = bytes / 1024;
return bytes + " ZB";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment