2

私は現在、ゲームのネットコードでシリアル化と逆シリアル化に と を丁重に使用bytestringattoparsecています。私はもともとこれらのライブラリを使用することに惹かれていました。cerealこれは、有用な割り当て戦略低レベルのプリミティブbytestringなど、ビルダーをかなり細かく制御できるためです。プロジェクトの後半で発生する可能性のあるレイテンシや GC の問題に対処するための準備が整うので、これは良い選択だと思いました。

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

機能が欠落している場合、この機能を追加する通常の方法は何ですか? ライブラリを使用して署名されたショーツをデコードする必要があるのは、私が初めてではありません。この機能が存在しない理由はありますか? 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))

これは内部で行うことcerealbinaryあり、当面この機能を取得するために現在行っていることですが、 APIで既に提供されていることbytestringを行うためにアドホックで安全でない関数を使用する必要がないのは良いことです。 .cerealbinary

低遅延のネットワーク環境で attoparsec を使用して、、、 、 、Int64Int32取り組む必要がある場合、ほとんどの人は何をしますか?Int16Int8Word64Word32Word16

(初心者向けの注意) ここには、素朴な仮定があります。およびcerealでの実装よりも、ネットワーク パケットの処理が高速ではないと暗黙的に想定しています。この仮定は、binary-serialise-cborでかなり大量の割り当てが行われていることを指摘するいくつかの講演を見てから生まれました。bytestringattoparseccerealbinaryこれは、バッファ内のバイナリ データのエンコードとデコードに対する継続的なアプローチによるものです。私は、エンコード/デコード サブルーチンが以前に見たフィールドの値に依存する時折のフィールドを使用して、非常に簡単でステートレスな方法でエンコードおよびデコードできることが多いネットワーク パケットを扱っています。ここでリアリティチェックが必要なのかもしれませんが、仕事に間違ったツールを使用していますか? 状況を改善するために、この高レベルでできることはあまりないのではないでしょうか? この場合、「時期尚早に最適化しない」は当てはまらないと仮定します。

4

1 に答える 1

1

パケットで何をしているのかをより詳細に説明する必要があります。ほとんどのネットワーク パケット処理はバックトラッキングを必要としないため、attoparsec はやや過剰です。また、attoparsec (およびバイナリとシリアル) では、パケットのすべてのバイトにアクセスする必要があります。ただし、ほとんどのネットワーク パケット内のフィールドの位置は固定オフセットにあります。したがって、ヘッダーを調べてパケットの種類を特定したら、フィールドに「ランダムにアクセス」できます。

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

于 2016-06-19T05:02:30.080 に答える