2016-06-19 1 views
1

私は現在、ゲームのネットコードで丁寧にシリアル化とデシリアライズを行うために、bytestringattoparsecを使用しています。私はもともとcerealよりもこれらのライブラリを使用することに惹きつけられました。なぜなら、bytestringは、有用なalloctation strategieslow-level primativesを含む、ビルダーよりかなり細かい制御を与えるからです。私は、プロジェクトで後で実行することができるレイテンシー/ GCの問題に対処するための設備が整っていることを確認するため、良い選択だと思っていました。Attoparsec:Data.WordとData.Intのデータ型を簡単に解析できますか?

そしてbytestring一つは、パケットフィールド(主にWord16ようData.WordData.Intで見つかったタイプ、Word16、およびInt8)で遭遇する一般的なデータ型にコンビネータの多くを提供しながら、私は任意の補完を見つけることができなかったとき、私はがっかりしましたコンビネータはattoparsecです。何か不足していますか?私は、提供されたコンビネータと同等のものを模倣することができますか?

機能が不足している場合は、この機能を追加する通常の方法は何ですか?私は確かに、ライブラリと署名されたショートを解読する必要がある最初のものではありません。この機能が存在しない理由はありますか?共通の図書館がありますか?私には分かりませんが、attoparsecを補足する必要がありますか?これは内部的に何をすべきかcerealbinaryであると私は現在、当分の間、この機能を得るためにやっているが、使用する必要はありませんしいいだろうので

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)) 

:または私はこのような何かを行う必要がありますbytestringcereal、およびbinaryがAPIで既に提供しているものを実行するために、アドホックで安全でない機能を使用します。彼らは、低遅延ネットワーク環境でattoparsecでInt64Int32Int16Int8Word64Word32、およびWord16に取り組む必要がある場合

は、ほとんどの人は何をしますか?

(NEWBIE NOTE)ここでは、ナイーブでもよいという前提があります。私は暗黙のうちにcerealbytestringattoparsecの実装よりもネットワークパケットを処理する方が高速ではないと仮定しています。この仮定は、バッファ内のバイナリデータの符号化および復号化に対する継続的なアプローチのために、cerealおよびbinaryで行われるかなり多くの割り当てを指すtalks coming out on binary-serialise-cborの一部を見たことに由来していました。私はしばしばエンコード/デコードサブルーチンが以前に見たフィールドの値に依存しているときどきのフィールドで、かなり簡単でステートレスな方法でエンコードおよびデコードできるネットワークパケットを扱っています。たぶん私はここで現実のチェックが必要な仕事のための間違ったツールを使用していますか?私の状況を改善するために、この高レベルで私ができることは本当にないのでしょうか?この場合、「時期尚早に最適化しないでください」は適用されないとします。

+0

'B.unsafeIndex'は文字列が十分に長いと分かっていれば完全に安全です。 – ErikR

答えて

1

パケットで何をしているのかを詳しく説明する必要があります。ほとんどのネットワークパケット処理はバックトラッキングを必要としないため、attoparsecは多少不合理です。また、attoparsec(およびバイナリとシリアル)では、パケットのすべてのバイトを参照する必要があります。しかし、ほとんどのネットワークパケット内のフィールドの位置は、固定のオフセットにあります。したがって、ヘッダーを調べた後、フィールドに「ランダムにアクセス」して、どのようなパケットがあるかを判断することができます。

ゼロ割り当ての実装を実現できると思います。C言語で行うようなアルゴリズムを書いてください:パケットデータを変更可能なボックス化されていないベクトルにロードしてください。現在のパケットの開始点へのオフセットを保持する。バッファに完全なパケットがない場合は、ベクターの先頭に移動し、残りのパケットデータを新しいパケットデータで埋めてください。

関連する問題