c # Binaryformatter медленный

Я использовал BinaryFormatter для сериализации / десериализации объектов в байтовый массив. Но это слишком медленно. Вот мой код:

IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, this);
stream.Close();
byte[] currentByteArray = stream.ToArray();

Можно ли улучшить этот код, чтобы ускорить его. Или какие у меня альтернативы? Я видел несколько других сериализаторов, таких как xmlserialization, но я не хочу записывать его в файл, просто как массив байтов.

Заранее спасибо!


person random    schedule 19.11.2015    source источник
comment
Укажите в вопросе код класса и показатели.   -  person Oguz Ozgul    schedule 19.11.2015
comment
Кроме того, насколько велики сериализованные данные? о каком размере мы здесь говорим?   -  person lordkain    schedule 19.11.2015
comment
stream.Close(); должен быть после byte[] currentByteArray = stream.ToArray();, а не до   -  person Dmitry Bychenko    schedule 19.11.2015
comment
Вы сериализуете объекты данных? как для общения?   -  person Jeroen van Langen    schedule 19.11.2015
comment
@DmitryBychenko Нет. Он должен быть в блоке finally после .ToArray(). Фактически, поток должен быть просто using блоком.   -  person Aron    schedule 19.11.2015
comment
Данные сериализуются до 10 МБ, это занимает около 200 мс. Да, это объекты данных, используемые при общении.   -  person random    schedule 19.11.2015
comment
Предлагаем вам попробовать запустить профилировщик и посмотреть, что он вам говорит. Чтобы начать работу, посетите здесь. В вашем вопросе недостаточно информации, чтобы мы могли определить, не делаете ли вы что-нибудь особенно плохое с BinaryFormatter. См. Самый быстрый способ сериализации и десериализации объекта .NET для сравнения сериализаторов.   -  person dbc    schedule 20.11.2015
comment
Решением может быть альтернативный сериализатор (отказ от ответственности: написано мной). Но обратите внимание, что использование двоичных сериализаторов также имеет проблемы с безопасностью.   -  person György Kőszeg    schedule 09.04.2021


Ответы (1)


Ваш код можно улучшить, если вы поместите утилизацию в оператор finally, как сказали ребята в комментариях:

IFormatter formatter;
MemoryStream stream;
try
{
    formatter = new BinaryFormatter();
    stream = new MemoryStream();
    formatter.Serialize(stream, this);
    byte[] currentByteArray = stream.ToArray();
}
finally
{
   if(stream!=null)
      stream.Close();
}

Однако приведенный выше код не улучшает производительность класса BinaryFormatter, потому что он работает и используется правильно. Но вы можете использовать другие библиотеки.

Один из самых быстрых и универсальных сериализаторов в .NET - это Protobuf-net. Например:

[ProtoContract]
class SubMessageRepresentations
{
   [ProtoMember(5, DataFormat = DataFormat.Default)] 
   public SubObject lengthPrefixedObject;
   [ProtoMember(6, DataFormat = DataFormat.Group)]
   public SubObject groupObject;
}

[ProtoContract(ImplicitFields=ImplicitFields.AllFields)]
class SubObject { public int x; }


using (var stream = new MemoryStream()) {
  _pbModel.Serialize(
   stream, new SubMessageRepresentations {
        lengthPrefixedObject = new SubObject { x = 0x22 },
        groupObject = new SubObject { x = 0x44 }
   });
byte[] buf = stream.GetBuffer();
for (int i = 0; i < stream.Length; i++)
Console.Write("{0:X2} ", buf[i]);
}
person StepUp    schedule 19.11.2015