2016-06-19 3 views
1

현재 게임 넷 코드에서 일련 번호 및 직렬화 해제에 대해 bytestringattoparsec을 사용하고 있습니다. 원래는 cereal 이상의 라이브러리를 사용하여 매력적이었습니다. 왜냐하면 bytestring이 도움이되는 alloctation strategieslow-level primatives을 포함하여 빌더보다 꽤 미세한 제어를하기 때문입니다. 나중에 프로젝트에서 실행할 수있는 대기 시간/GC 문제를 처리 할 수있는 장비가 잘 갖추어 졌는지 확인하는 것이 좋은 선택 일 것이라고 생각했습니다. 내가 어떤 보완을 찾을 수 없습니다 때Attoparsec : Data.Word 및 Data.Int에서 데이터 형식을 파싱하는 더 쉬운 방법?

그리고 bytestring 일반적인 데이터 유형 콤비를 많이 제공하면서 하나의 패킷 필드에서 발생할 것 (주로 Data.WordWord16 같은 Data.Int, Word16에서 발견되는 유형 및 Int8은), 나는 실망했다 combinators in 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)) 

: 아니면 내가 이런 일을해야 임의의 안전하지 않은 기능을 사용하여 bytestring, cerealbinary이 이미 API에서 제공하는 작업을 수행 할 수 있습니다. 그들이 해결해야 할 때

대부분의 사람들은 무엇을해야합니까 Int64, Int32, Int16, Int8, Word64, 낮은 지연 시간 네트워킹 환경에서 attoparsec와 Word32Word16?

(NEWBIE 참고 사항) 여기에는 단순한 가정이 있습니다. 나는 암시 적으로 cerealbytestringattoparsec에있는 구현보다 네트워크 패킷을 다루는 속도가 빠르다고 가정하고있다. 이 가정은 talks coming out on binary-serialise-cbor 중 일부가 버퍼의 이진 데이터 인코딩 및 해독에 대한 지속적인 접근 방식으로 인해 cerealbinary에서 발생하는 다소 많은 양의 할당을 가리키는 것을보고 발생했습니다. 저는 종종 인코딩/디코딩 서브 루틴이 이전에 본 필드의 값에 의존하는 가끔 필드를 사용하여 매우 간단하고 상태 비 저장 방법으로 인코딩 및 디코딩 할 수있는 네트워크 패킷을 다루고 있습니다. 어쩌면 내가 여기 현실 확인이 필요하고 직업에 대한 잘못된 도구를 사용하고 있습니까? 내 상황을 개선하기 위해이 고수준에서 할 수있는 일이 정말로 없을 것 같은가? 이 경우 "조기에 최적화하지 마십시오"는 적용 할 수 없다고 가정합니다.

+0

'B.unsafeIndex'는 문자열이 충분히 길다는 것을 알고 있으면 완벽하게 안전합니다. – ErikR

답변

1

패킷으로 무엇을하고 있는지 더 자세히 설명해야합니다. 대부분의 네트워크 패킷 처리에는 역 추적이 필요하지 않으므로 attoparsec은 다소 과도합니다. 또한 attoparsec (및 바이너리 및 시리얼)은 패킷의 모든 바이트를 방문해야합니다. 그러나 대부분의 네트워크 패킷 내의 필드 위치는 고정 된 오프셋에 있습니다. 따라서 어떤 종류의 패킷을 가지고 있는지 확인하기 위해 헤더를 검사하면 필드에 "무작위로 액세스"할 수 있습니다.

제로 할당 구현을 달성 할 수 있다고 생각합니다. C에서 수행하는 것처럼 알고리즘을 작성하십시오. 패킷 데이터를 변경 가능한 unboxed 벡터로로드하십시오. 현재 패킷의 시작 부분에 오프셋을 유지; 버퍼에 완전한 패킷이없는 경우에는 벡터의 맨 위로 옮긴 다음 나머지를 새 패킷 데이터로 채 웁니다.