我目前正在游戏网络代码中恭敬地使用bytestring
和进行序列化和反序列化。attoparsec
我最初被这些库所吸引,cereal
因为它对bytestring
Builders 提供了非常细粒度的控制,包括有用的分配策略和低级primatives 。我认为这将是一个不错的选择,因为它可以确保我能够更好地处理我在项目后期可能遇到的任何延迟/GC 问题。
虽然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
的APIcereal
中binary
已经提供的内容.
当大多数人需要在低延迟网络环境中处理Int64
, Int32
, Int16
, Int8
, Word64
, Word32
, 和attoparsec 时,他们会怎么做?Word16
(NEWBIE NOTE)这里有一个可能很幼稚的假设。我隐含地假设cereal
处理网络数据包的速度并不比 和 中的实现bytestring
快attoparsec
。这个假设起源于观看有关 binary-serialise-cbor 的一些谈话,这些谈话指出相当大量的分配发生在cereal
和binary
由于他们在缓冲区中编码和解码二进制数据的延续方法。我正在处理网络数据包,这些数据包通常可以以一种非常简单和无状态的方式进行编码和解码,其中偶尔出现的字段的编码/解码子例程取决于先前看到的字段的值。也许我需要在这里进行现实检查并且我使用了错误的工具来完成这项工作?也许在这个高层次上我真的没有什么可以做的来改善我的处境?假设“不要过早优化”在这种情况下不适用。