如何比较messagepack-cli和json.net反序列化器的性能

本文关键字:net json 反序列化 性能 messagepack-cli 何比较 比较 | 更新日期: 2023-09-27 18:09:54

我试图比较Unity3d中两种不同的反序列化方法的性能,这是基于MonoDevelop对c#/.NET的实现

方法A)使用MsgPack-CLI

方法B)使用NewtonSoft的Json。净

基于这篇博文,我的印象是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倍…这看起来很奇怪吗?这是我试图序列化/反序列化的类的形式:

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; }
}

如何比较messagepack-cli和json.net反序列化器的性能

经过一些尝试和错误后,我发现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类来改进,尽管我还没有实现。