Как сравнить производительность десериализаторов 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, хотя я еще не реализовал.