如何比较 messagepack-cli 和 json.net 反序列化器的性能?
How to compare performance of messagepack-cli and json.net deserializers?
我正在尝试比较 Unity3d 中两种不同反序列化方法的性能,Unity3d 是基于 MonoDevelop 对 C# / .NET 的实现
方法 A) 使用 MsgPack-CLI
方法 B) 使用 NewtonSoft's Json.NET
基于此 blog post,我的印象是 Messagepack 的读写速度更快。但是,我发现虽然写入性能明显更好,但读取性能明显变慢。
出于测试反序列化性能的目的,我在这段代码中做错了吗?
public void test_msgpack(int _num, Test_Class _obj)
{
var serializer = MessagePackSerializer.Get< Test_Class >();
var stream = new MemoryStream();
serializer.Pack(stream, _obj);
Stopwatch stopWatch = new Stopwatch ();
stopWatch.Start ();
while (_num > 0) {
_num -= 1;
stream.Position = 0;
Test_Class deserializedObject = serializer.Unpack( stream );
}
stopWatch.Stop ();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format ("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
print ("msgpack read: " + elapsedTime);
}
public void test_json(int _num, Test_Class _obj)
{
var serializer = new JsonSerializer();
var stream = new MemoryStream();
var sw = new StreamWriter(stream);
var JsonTextWriter = new JsonTextWriter(sw);
var sr = new StreamReader(stream);
var JsonTextReader = new JsonTextReader(sr);
serializer.Serialize(JsonTextWriter, _obj);
Stopwatch stopWatch = new Stopwatch ();
stopWatch.Start ();
while (_num > 0) {
_num -= 1;
stream.Position = 0;
Test_Class deserializedObject = serializer.Deserialize<Test_Class>(JsonTextReader);
}
stopWatch.Stop ();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format ("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
print ("json read: " + elapsedTime);
}
我发现 JSON 解析性能在 100000 次迭代中大约快 100 倍...这看起来很奇怪?这是我尝试序列化/反序列化的 class 的形式:
public class Test_Class
{
public string i { get; set; }
public List<float> a { get; set; }
public List<float> b { get; set; }
public List<float> c { get; set; }
}
经过反复试验,我发现 JSON.net 代码返回了一个空对象,因此性能显着提高。我通过如下修改 test_json 方法来解决这个问题:
public void test_json(int _num, Test_Class _obj)
{
JsonSerializer serializer = new JsonSerializer();
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
JsonTextWriter jsonWriter = new JsonTextWriter(writer);
serializer.Serialize(jsonWriter, _obj);
jsonWriter.Flush();
Stopwatch stopWatch = new Stopwatch ();
stopWatch.Start ();
while (_num > 0) {
_num -= 1;
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
JsonTextReader jsonReader = new JsonTextReader(reader);
Test_Class deserialised_object = serializer.Deserialize<Test_Class>(jsonReader);
}
stopWatch.Stop ();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format ("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
print ("json read: " + elapsedTime);
}
jsonWriter.Flush() 方法是必需的,每次读取时都需要创建一个新的 JsonTextReader。
结果仍然显示 JSON.net 反序列化速度更快,但是,这种差异现在更小了。 MsgPack-CLI 的性能显然可以通过使用 SerializerGenerator class 来提高,尽管我还没有实现。
我正在尝试比较 Unity3d 中两种不同反序列化方法的性能,Unity3d 是基于 MonoDevelop 对 C# / .NET 的实现
方法 A) 使用 MsgPack-CLI
方法 B) 使用 NewtonSoft's Json.NET
基于此 blog post,我的印象是 Messagepack 的读写速度更快。但是,我发现虽然写入性能明显更好,但读取性能明显变慢。
出于测试反序列化性能的目的,我在这段代码中做错了吗?
public void test_msgpack(int _num, Test_Class _obj)
{
var serializer = MessagePackSerializer.Get< Test_Class >();
var stream = new MemoryStream();
serializer.Pack(stream, _obj);
Stopwatch stopWatch = new Stopwatch ();
stopWatch.Start ();
while (_num > 0) {
_num -= 1;
stream.Position = 0;
Test_Class deserializedObject = serializer.Unpack( stream );
}
stopWatch.Stop ();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format ("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
print ("msgpack read: " + elapsedTime);
}
public void test_json(int _num, Test_Class _obj)
{
var serializer = new JsonSerializer();
var stream = new MemoryStream();
var sw = new StreamWriter(stream);
var JsonTextWriter = new JsonTextWriter(sw);
var sr = new StreamReader(stream);
var JsonTextReader = new JsonTextReader(sr);
serializer.Serialize(JsonTextWriter, _obj);
Stopwatch stopWatch = new Stopwatch ();
stopWatch.Start ();
while (_num > 0) {
_num -= 1;
stream.Position = 0;
Test_Class deserializedObject = serializer.Deserialize<Test_Class>(JsonTextReader);
}
stopWatch.Stop ();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format ("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
print ("json read: " + elapsedTime);
}
我发现 JSON 解析性能在 100000 次迭代中大约快 100 倍...这看起来很奇怪?这是我尝试序列化/反序列化的 class 的形式:
public class Test_Class
{
public string i { get; set; }
public List<float> a { get; set; }
public List<float> b { get; set; }
public List<float> c { get; set; }
}
经过反复试验,我发现 JSON.net 代码返回了一个空对象,因此性能显着提高。我通过如下修改 test_json 方法来解决这个问题:
public void test_json(int _num, Test_Class _obj)
{
JsonSerializer serializer = new JsonSerializer();
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
JsonTextWriter jsonWriter = new JsonTextWriter(writer);
serializer.Serialize(jsonWriter, _obj);
jsonWriter.Flush();
Stopwatch stopWatch = new Stopwatch ();
stopWatch.Start ();
while (_num > 0) {
_num -= 1;
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
JsonTextReader jsonReader = new JsonTextReader(reader);
Test_Class deserialised_object = serializer.Deserialize<Test_Class>(jsonReader);
}
stopWatch.Stop ();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format ("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
print ("json read: " + elapsedTime);
}
jsonWriter.Flush() 方法是必需的,每次读取时都需要创建一个新的 JsonTextReader。
结果仍然显示 JSON.net 反序列化速度更快,但是,这种差异现在更小了。 MsgPack-CLI 的性能显然可以通过使用 SerializerGenerator class 来提高,尽管我还没有实现。