Оптимальная сериализация типов примитивов

Была та же проблема, решенная обновлением узла до последней версии lts (10.15.1)

6
задан Peter Mortensen 8 July 2017 в 01:36
поделиться

8 ответов

(касается сообщений/классов, не просто примитивов),

Google разработал "буферы протокола" для этого типа сценария (они смещают огромный объем данных вокруг) - их формат компактен (использование вещей как основа 128 кодирования), но расширяем и терпимая версия (таким образом, клиенты и серверы могут обновить легко).

В мире.NET я могу рекомендовать 2 буферных реализации протокола:

Для получения информации protobuf-сеть имеет прямую поддержку ISerializable и дистанционная работа (это - часть модульных тестов). Здесь существуют метрики производительности/размера.

И лучший из всех, все, что Вы делаете, добавляют несколько атрибутов к Вашим классам.

Протест: это не утверждает, что было теоретическим лучшим - но прагматичный и легкий разобраться - компромисс между производительностью, мобильностью и простотой.

5
ответ дан 10 December 2019 в 00:45
поделиться

Проверьте основу 128 типов varint, используемых в буферах протокола Google; это могло бы быть тем, что Вы ищете.

(Существует много реализаций.NET буферов протокола, доступных при поиске сети, от которой, в зависимости от их лицензии, Вы смогли унижаться некоторый код!)

2
ответ дан 10 December 2019 в 00:45
поделиться

Если Ваши массивы могут быть отсортированы, можно выполнить простой RLE для оставления свободного места. Даже если они не отсортированы, RLE может все еще быть выгодным. Это быстро для реализации и для записи и для чтения.

1
ответ дан 10 December 2019 в 00:45
поделиться

Прежде, чем реализовать ISerializable самостоятельно, Вы, вероятно, использовали XmlSerializer или средство форматирования SOAP в веб-сервисе. Учитывая Вас имеют все толстые клиенты вся рабочая.NET, Вы могли попытаться использовать BinaryFormatter.

-1
ответ дан 10 December 2019 в 00:45
поделиться

Если Вы знаете, какие международные значения более распространены, можно закодировать те значения в меньшем количестве битов (и закодировать меньшее-количество-общие-ценности, использующее соответственно больше битов): это называют кодированием/кодированием/сжатием "Хаффмана".

В целом, хотя я предложил бы, чтобы одна из самых легких вещей, которые Вы могли сделать, состояла в том, чтобы выполнить стандартную 'zip' или утилиту 'сжатия' по Вашим данным.

0
ответ дан 10 December 2019 в 00:45
поделиться

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

  1. Элементы массива группы в группах 4.
  2. Предшествуйте каждой группе с байтом (давайте назовем ее маской длины), который указывает на длину следующих 4 элементов. Маска длины является битовой маской, состоявшей из дибитов, которые указывают, какой длины соответствующий элемент (00 - 1 байт, 01 - 2 байта, 10 - 3 байта, 11 - 4 байта).
  3. Выпишите элементы, столь короткие, как Вы можете.

Например, для представления целых чисел без знака 0x0000017B, 0x000000A9, 0xC247E8AD и 0x00032A64, Вы записали бы (принятие прямого порядка байтов): B1, 7B, 01, A9, AD, E8, 47, C2, 64, 2 А, 03.

Это может сохранить Вас до 68,75% (11/16) пространства в лучшем случае. В худшем случае Вы на самом деле потратили бы впустую дополнительные 6,25% (1/16).

1
ответ дан 10 December 2019 в 00:45
поделиться

Для целого числа, если у Вас обычно есть небольшие числа (под 127 или 32768) можно закодировать число с помощью MSB в качестве флага, чтобы определить, является ли это последний байт или нет. Немного подобный UTF-8, но флаговому биту на самом деле потрачен впустую (который не имеет место с UTF-8),

Пример (обратный порядок байтов):

125 which is usually encoded as 00 00 00 7D
Could be encoded as 7D

270 which is usually encoded as 00 00 01 0E
Could be encoded as 82 0E

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

Этот метод на самом деле используется в старых форматах, таких как MIDI, потому что старой электронике были нужны очень эффективные и простые методы кодирования.

0
ответ дан 10 December 2019 в 00:45
поделиться

Да, есть необычный способ сериализации примитивных типов. В качестве бонуса он также намного быстрее (обычно в 20-40 раз).

Библиотека с открытым исходным кодом Саймона Хьюитта, см. Оптимизация сериализации в .NET - часть 2 , использует различные приемы. Например, если известно, что массив содержит маленькие целые числа, то на сериализованный вывод будет отправлено меньше. Это подробно описано в части 1 статьи . Например:

... Итак, Int32 меньше чем 128 может быть сохранено в одном байте (при использовании 7-битного encoding) ....

Полное и оптимизированное по размеру целые числа можно смешивать и сопоставлять. Это может показаться очевидным, но есть и другие вещи; например, для целочисленного значения 0 происходят особые вещи - оптимизация для хранения числового типа и нулевого значения.

В части 1 говорится:

... Если вы когда-либо использовали удаленное взаимодействие .NET для больших объемов данных, вы обнаружит, что есть проблемы с масштабируемостью. Для небольших объемов данных он работает достаточно хорошо, но большие объемы требуют много ресурсов ЦП и памяти, генерируют большие объемы данных для передачи и могут давать сбой из-за исключений Out Of Memory. Также существует большая проблема со временем, затрачиваемым на фактическое выполнение сериализации - большие объемы данных могут сделать его невозможным для использования в приложениях ....

Я с большим успехом использовал эту библиотеку в моем приложении . ASSERT 0 , Debug.WriteLine () или аналогичный в место в код библиотеки, где он возвращается к сериализации .NET. Это конец функции WriteObject () в файле FastSerializer.cs , рядом с createBinaryFormatter (). Serialize (BaseStream, value); .

2
ответ дан 10 December 2019 в 00:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: