Attoparsec: более простой способ анализа типов данных из Data.Word и Data.Int?

Я сейчас пользуюсь bytestring а также attoparsec за сериализацию и десериализацию с уважением в игровом сетевом коде. Я был изначально привлечен к использованию этих библиотек cereal так как bytestring дает довольно детальный контроль над строителями, включая полезные стратегии распределения и низкоуровневые приматы. Я подумал, что это будет хороший выбор, так как он обеспечит мое лучшее оснащение для решения любых проблем с задержкой / сборкой мусора, с которыми я могу столкнуться позже в проекте.

И пока bytestring предоставляет множество комбинаторов для общих типов данных, с которыми можно столкнуться при работе с полями пакетов (в основном это типы, найденные в Data.Word а также Data.Int лайк Word16, Word16, а также Int8), Я был разочарован, когда не смог найти никаких дополнительных комбинаторов в attoparsec, Я что-то пропустил? Могу ли я сделать что-то эквивалентное с помощью предоставленных комбинаторов?

Если это так, что функциональность отсутствует, каков обычный способ добавления этой функциональности? Я, конечно, не первый, кому нужно декодировать подписанные шорты в библиотеке. Есть ли причина, по которой эта функциональность не существует? Есть ли общая библиотека, которую я должен дополнить attoparsec с чем я не знаю? Или я должен сделать что-то вроде этого:

import           Data.Bits
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import qualified Data.Attoparsec.ByteString as Decode
import           Data.Int


decodeInt16BE :: Decode.Parser Int16
decodeInt16BE = do
  bs <- Decode.take 2
  return $! (fromIntegral (bs `B.unsafeIndex` 0) `shiftL` 8) .|.
            (fromIntegral (bs `B.unsafeIndex` 1) 1))

Потому что это то, что cereal а также binary делать внутренне и то, что я в настоящее время делаю, чтобы получить эту функциональность в настоящее время, но было бы неплохо не использовать специальные небезопасные функции, чтобы сделать то, что bytestring, cereal, а также binary уже предоставляют в своих API.

Что делает большинство людей, когда им нужно заняться Int64 , Int32 , Int16 , Int8 , Word64 , Word32 , а также Word16 с attoparsec в сетевой среде с низкой задержкой?

(NEWBIE NOTE) Здесь есть предположение, которое может быть наивным. Я неявно предполагаю cereal не быстрее для обработки сетевых пакетов, чем реализации в bytestring а также attoparsec, Это предположение возникло из-за просмотра некоторых выступлений на двоичном-serialise-cbor, которые указывают на довольно большое количество распределений, происходящих в cereal а также binary благодаря их продолжению подход к кодированию и декодированию двоичных данных в буферах. Я имею дело с сетевыми пакетами, которые часто могут быть закодированы и декодированы довольно простым способом без сохранения состояния со случайным полем, подпрограмма кодирования / декодирования которого зависит от значения ранее увиденного поля. Может быть, мне нужна проверка в реальных условиях, и я использую не те инструменты для работы? Может быть, на самом высоком уровне я ничего не могу сделать, чтобы улучшить свою ситуацию? Предположим, что "не преждевременно оптимизировать" не применимо в этом случае.

1 ответ

Вы должны объяснить более подробно, что вы делаете с пакетами. Большая часть обработки сетевых пакетов не требует обратного отслеживания, поэтому attoparsec несколько избыточен. Кроме того, attoparsec (и двоичный и зерновой) требует, чтобы вы посещали каждый байт пакета. Однако местоположения полей в большинстве сетевых пакетов имеют фиксированные смещения. Таким образом, вы можете "произвольно обращаться" к полям, как только вы изучите заголовок, чтобы определить, какой тип пакета у вас есть.

Я думаю, что вы можете достичь (почти) реализации с нулевым распределением - просто напишите свой алгоритм, как вы делали бы это в C: загрузите ваши пакетные данные в изменяемый распакованный вектор; сохранить смещение к началу текущего пакета; если у вас нет полного пакета в буфере, переместите то, что у вас есть, в начало вектора и заполните остальные новые данные пакета.

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