Как сравнить производительность десериализаторов messagepack-cli и json.net?

Я пытаюсь сравнить производительность двух разных методов десериализации в Unity3d, которая основана на реализации MonoDevelop C# / .NET

Способ А) Использование MsgPack-CLI

Метод Б) Использование NewtonSoft's Json.NET

Основываясь на этом сообщении в блоге, у меня сложилось впечатление, что 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 примерно в 100 раз выше 100000 итераций... что странно? Вот форма класса, который я пытаюсь сериализовать / десериализовать:

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

1 ответ

Решение

После некоторых проб и ошибок я обнаружил, что код 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, хотя я еще не реализовал.

Другие вопросы по тегам