문제

이 라이브러리에 대한 경험이 있는 사람 중 자신이 선호하는 라이브러리에 대해 의견이 있는 사람이 있습니까?성능 차이나 사용상의 어려움은 없었나요?

도움이 되었습니까?

해결책

나는 두 시스템 모두에서 조금 놀았고, 진지한 것은없고, 단순한 해킹 된 것들을 가지고 있었지만, 라이브러리를 사용하는 방법에는 실제로 차이가 있다고 느꼈습니다.

부스트 :: 직렬화를 통해 먼저 자신의 스트러크/클래스를 작성한 다음 아카이빙 방법을 추가하지만 여전히 데이터 구성원으로 사용될 수있는 예쁜 "슬림"클래스가 남아 있습니다.

프로토콜 버퍼를 사용하면 간단한 구조를 위해 생성 된 코드의 양은 상당히 상당하며 생성 된 structs and code는 작동하기위한 것이며 프로토콜 버퍼의 기능을 사용하여 자체 내부 구조로 데이터를 전송합니다. .

다른 팁

나는 오랫동안 부스트 직렬화를 사용해 왔으며 프로토콜 버퍼를 파헤 쳤으며 정확히 같은 목적이 없다고 생각합니다. BS (다가오는 것을 보지 못함)는 C ++ 객체를 스트림에 저장하는 반면 PB는 읽은 교환 형식입니다.

PB의 Datamodel은 훨씬 간단합니다. 모든 종류의 ints와 floats, strings, array, 기본 구조를 얻을 수 있습니다. BS를 사용하면 모든 객체를 한 단계로 직접 저장할 수 있습니다.

즉, BS의 경우 와이어에 대한 더 많은 데이터를 얻을 수 있지만 모든 객체 구조를 재건 할 필요는 없지만 프로토콜 버퍼는 더 컴팩트하지만 아카이브를 읽은 후에해야 할 작업이 더 많습니다. 이름에서 알 수 있듯이, 하나는 프로토콜 (언어-공간, 공간 효율적인 데이터 전달) 용이며, 다른 하나는 직렬화 (끔찍한 개체 절약)를위한 것입니다.

그렇다면 당신에게 더 중요한 것은 속도/공간 효율 또는 깨끗한 코드입니까?

Boost.serialization과 관련하여 몇 가지 추가 우려 사항이 있습니다. 경고 : 문서를 훑어 보는 것 이상의 프로토콜 버퍼에 대한 직접적인 경험이 없습니다.

Boost와 Boost.serialization은 그것이하는 일에 훌륭하다고 생각하지만, 기본 아카이브 형식이 와이어 형식에 좋은 선택이 아니라는 결론에 도달했습니다.

버전을 구별하는 것이 중요합니다 당신의 수업 (다른 답변에서 언급 한 바와 같이, 부스트 .Serialization은 데이터 버전화를 지원합니다) 다른 버전의 다른 버전 간의 호환성 직렬화 라이브러리.

새로운 버전의 boost.serialization 이전 버전이 필사적으로 변할 수있는 아카이브를 생성하지 못할 수 있습니다. (그 반대는 사실이 아닙니다 : 최신 버전은 항상 이전 버전으로 만든 아카이브를 사로화하기위한 것입니다). 이로 인해 우리에게는 다음과 같은 문제가 발생했습니다.

  • 클라이언트 및 서버 소프트웨어는 다른 사람이 소비하는 직렬화 된 객체를 생성하므로 클라이언트와 서버를 모두 Lockstep에서 업그레이드하면 최신 부스트로만 이동할 수 있습니다. (이것은 고객을 완전히 제어 할 수없는 환경에서는 매우 어려운 일입니다).
  • 부스트는 공유 부품이있는 하나의 큰 라이브러리로 번들로 제공되며 직렬화 코드와 부스트 라이브러리의 다른 부분 (예 : Shared_PTR)이 동일한 파일에 사용될 수 있습니다. 업그레이드 할 수 없습니다. 어느 부스트를 업그레이드 할 수 없기 때문에 부스트의 일부. 여러 버전의 부스트를 단일 실행 파일에 연결하려고 시도하는 것이 가능/안전한/제정신이 확실하지 않거나, 구식 버전의 부스트를 별도로 유지 해야하는 비트를 리팩토링하기 위해 예산/에너지가 있는지 여부가 확실하지 않습니다. 실행 파일 (우리의 경우 DLL).
  • 우리가 갇힌 Boost의 기존 버전은 우리가 사용하는 최신 버전의 컴파일러를 지원하지 않으므로 오래된 버전의 컴파일러에도 붙어 있습니다.

Google은 실제로 보입니다 프로토콜 버퍼 와이어 형식을 게시하십시오, Wikipedia는 그것들을 다음과 같이 설명합니다 전방 호환, 후진 호환 (Wikipedia는 프로토콜 버퍼 라이브러리 버전화보다는 데이터 버전화를 언급하고 있다고 생각합니다). 이들 중 어느 것도 전방 호환성을 보장하는 것이 아니지만, 그것은 나에게 더 강한 표시처럼 보입니다.

요약해서 말하자면, 잘 알려진 출판 된 와이어 형식을 선호합니다 Lockstep에서 클라이언트 및 서버를 업그레이드 할 수없는 경우 프로토콜 버퍼처럼.

각주 : 부끄러운 플러그 관련 답변 나에게서부터로.

직렬화를 향상시킵니다

  • 스트림에 데이터를 작성하는 라이브러리입니다.
  • 데이터를 압축하지 않습니다.
  • 데이터 버전 작성을 자동으로 지원하지 않습니다.
  • STL 컨테이너를 지원합니다.
  • 작성된 데이터의 특성은 선택한 스트림 (예 : 엔디 언, 압축)에 따라 다릅니다.

프로토콜 버퍼

  • 인터페이스 설명에서 코드를 생성합니다 (기본적으로 C ++, Python 및 Java를 지원합니다. C, C# 및 기타 타사는 타사).
  • 선택적으로 데이터를 압축합니다.
  • 데이터 버전화를 자동으로 처리합니다.
  • 플랫폼간에 엔디 언 교체를 처리합니다.
  • STL 컨테이너를 지원하지 않습니다.

부스트 직렬화는 객체를 직렬화 된 데이터 스트림으로 변환하기위한 라이브러리입니다. 프로토콜 버퍼는 같은 작업을 수행하지만 버전 및 엔디언 스왑과 같은 다른 작업도 수행합니다. "작은 간단한 작업"의 경우 직렬화 부스트가 더 간단합니다. 프로토콜 버퍼는 아마도 "더 큰 인프라"에 더 좋습니다.

편집 : 24-11-10 : BS 버전에 "자동으로"추가되었습니다.

부스트 직렬화에 대한 경험은 없지만 프로토콜 버퍼를 사용했습니다. 나는 프로토콜 버퍼를 많이 좋아합니다. 다음을 명심하십시오 (나는 이것을 지식이 없습니다 부스트).

  • 프로토콜 버퍼는 매우 효율적이므로 그렇지 않습니다 상상하다 그것은 심각한 문제와 부스트입니다.
  • 프로토콜 버퍼는 다른 언어 (Python 및 Java ... 등)와 함께 작동하는 중간 표현을 제공합니다. C ++ 만 사용하고 있다는 것을 알고 있다면 부스트가 더 좋을 수도 있지만 다른 언어를 사용하는 옵션이 좋습니다.
  • 프로토콜 버퍼는 데이터 컨테이너와 비슷합니다 ... 상속과 같은 객체 지향 특성이 없습니다. 직렬화하고자하는 것의 구조에 대해 생각해보십시오.
  • "옵션"필드를 추가 할 수 있으므로 프로토콜 버퍼는 유연합니다. 이것은 기본적으로 호환성을 깨지 않고 프로토콜 버퍼의 구조를 변경할 수 있음을 의미합니다.

도움이 되었기를 바랍니다.

Boost.serialization은 C ++ 컴파일러가 필요하며 다음과 같은 구문 설탕을 제공합니다.

serialize_obj >> archive;
// ...
unserialize_obj << archive;

저장 및 로딩을 위해. C ++가 사용하는 유일한 언어 인 경우 부스트를 제공해야합니다.

Google 프로토콜 버퍼를 빠르게 살펴 보았습니다. 내가 본 바에 따르면, 나는 부스트와 직접 비교할 수 없다고 말합니다. .proto 파일에 대한 컴파일러를 도구 체인에 추가하고 .proto 파일 자체를 유지해야합니다. API는 Boost.serialization과 같이 C ++에 통합되지 않습니다.

Boost.serialization은 매우 잘 설계된 작업을 수행합니다. C ++ 객체를 직렬화하기 위해 :) OTOH Google 프로토콜 버퍼와 같은 쿼리 -API는 더 많은 유연성을 제공합니다.

지금까지 Boost.serialization 만 사용했기 때문에 성능 비교에 대해서는 언급 할 수 없습니다.

위의 내용을 수정합니다(아마도 그 대답) 부스트 직렬화에 대해 :

지원을 허용합니다 데이터 버전 관리.

압축이 필요한 경우 압축된 스트림을 사용하십시오.

인코딩은 텍스트, 바이너리 또는 XML일 수 있으므로 플랫폼 간의 엔디안 교환을 처리할 수 있습니다.

Boost의 라이브러리를 사용하여 아무것도 구현하지는 않았지만 Google Protobuff가 더 생각하는 것으로 나타 났으며 코드는 훨씬 깨끗하고 읽기 쉽습니다. 나는 당신이 그것을 사용하고 싶은 다양한 언어를 살펴보고 코드와 문서를 읽고 마음을 구성하는 것이 좋습니다.

내가 Protobufs에서 가지고있는 한 가지 어려움은 생성 된 코드 GetMessage ()에서 매우 일반적으로 사용되는 기능으로 지명되었으며, 이는 물론 Win32 GetMessage 매크로와 충돌합니다.

나는 여전히 protobufs를 강력히 추천 할 것입니다. 그들은 매우 유용합니다.

엔지니어링의 거의 모든 것과 마찬가지로 내 대답은 "의존합니다."

둘 다 잘 테스트되고 검증 된 기술이 있습니다. 둘 다 데이터를 가져 와서 어떤 곳을 보내는 데 친숙한 것으로 바꿀 것입니다. 둘 다 충분히 빠를 것입니다. 그리고 당신이 여기저기서 바이트를 실제로 세고 있다면, 당신은 아마도 어느 쪽에도 행복하지 않을 것입니다 (둘 다 만든 패킷은 XML 또는 JSON의 작은 부분이 될 것입니다).

저에게는 실제로 워크 플로우로 내려오고 다른 쪽 끝에 C ++ 이외의 다른 것이 필요한지 여부입니다.

메시지 내용을 먼저 파악하고 처음부터 시스템을 구축하려면 프로토콜 버퍼를 사용하십시오. 메시지를 추상적 인 방식으로 생각한 다음 원하는 언어로 코드를 자동 생성 할 수 있습니다 (제 3 자 플러그인은 거의 모든 것을 사용할 수 있습니다). 또한 프로토콜 버퍼로 협업이 단순화되어 있습니다. 방금 .proto 파일을 보내면 다른 팀은 어떤 데이터가 전송되는지 명확하게 아이디어를 가지고 있습니다. 나는 또한 그들에게 아무것도 부과하지 않습니다. 그들이 Java를 사용하고 싶다면 계속하십시오!

내가 이미 C ++로 클래스를 구축 한 경우 (그리고 이것은 자주 발생하지 않았다) 지금 해당 데이터를 전선으로 보내고 싶다면 직렬화를 강화하는 것은 분명히 많은 의미가있다 (특히 다른 곳에 이미 부스트 의존성이있는 곳에 ).

"실제"도메인 객체와 긴밀한 연속으로 부스트 직렬화를 사용하고 완전한 객체 계층 구조 (상속)를 직렬화 할 수 있습니다. Protobuf는 상속을 지원하지 않으므로 집계를 사용해야합니다. 사람들은 Protobuf가 핵심 도메인 객체 자체가 아닌 DTO (데이터 전송 객체)에 사용되어야한다고 주장합니다. Boost :: Serialization과 Protobuf를 모두 사용했습니다. 부스트 :: 직렬화 성능을 고려해야합니다. 시리얼 대안 일 수 있습니다.

이제 이것이 오래된 질문이라는 것을 알고 있지만 2펜스를 던져야겠다고 생각했습니다!

부스트를 사용하면 수업에 데이터 유효성 검사를 작성할 수 있는 기회가 생깁니다.이는 데이터 정의와 유효성 검사가 모두 한 곳에서 이루어지기 때문에 좋습니다.

GPB를 사용하면 할 수 있는 최선의 방법은 .proto 파일에 주석을 추가하고 이를 사용하는 사람이 누구나 이 파일을 읽고 주의를 기울이고 유효성 검사를 직접 구현하기를 바라는 것입니다.

말할 필요도 없이 네트워크 스트림의 반대편에 있는 다른 사람에게 자신과 동일한 활력으로 이 작업을 수행하는 경우 이는 가능성이 낮고 신뢰할 수 없습니다.또한 유효성에 대한 제약이 변경되면 여러 코드 변경을 계획하고 조정하고 완료해야 합니다.

따라서 저는 GPB가 모든 팀원과 정기적으로 만나 대화할 기회가 거의 없는 개발에는 부적절하다고 생각합니다.

==수정==

제가 말하고자 하는 바는 다음과 같습니다.

message Foo
{
    int32 bearing = 1;
}

이제 누가 유효한 범위가 무엇인지 말할 수 있습니까? bearing 이다?우리는 가질 수 있습니다

message Foo
{
    int32 bearing = 1;  // Valid between 0 and 359
}

하지만 이는 다른 누군가가 이 글을 읽고 코드를 작성하느냐에 달려 있습니다.예를 들어 편집하면 제약 조건은 다음과 같습니다.

message Foo
{
    int32 bearing = 1;  // Valid between -180 and +180
}

당신은 이 .proto를 사용하여 코드를 업데이트하는 모든 사람에게 전적으로 의존합니다.그것은 신뢰할 수 없고 비용이 많이 듭니다.

최소한 Boost 직렬화를 사용하면 단일 C++ 클래스를 배포하고 데이터 유효성 검사가 바로 내장될 수 있습니다.이러한 제약 조건이 변경되면 다른 누구도 귀하와 동일한 버전의 소스 코드를 사용하고 있는지 확인하는 것 외에는 다른 작업을 수행할 필요가 없습니다.

대안

대안이 있습니다:ASN.1.이것은 오래되었지만 정말 정말 편리한 기능이 있습니다.

Foo ::= SEQUENCE
{
   bearing INTEGER (0..359)
}

제약 조건을 참고하세요.따라서 누구나 이 .asn 파일을 사용하고 코드를 생성할 때마다 자동으로 확인하는 코드가 생성됩니다. bearing 0에서 359 사이입니다..asn 파일을 업데이트하면

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180)
}

그들이 해야 할 일은 다시 컴파일하는 것뿐입니다.다른 코드 변경은 필요하지 않습니다.

다음을 수행할 수도 있습니다.

bearingMin INTEGER ::= 0
bearingMax INTEGER ::= 360

Foo ::= SEQUENCE
{
   bearing INTEGER (bearingMin..<bearingMax)
}

참고하세요 <.또한 대부분의 도구에서bearingMin 및bearingMax는 생성된 코드에서 상수로 나타날 수 있습니다.그것은 매우 유용합니다.

제약조건은 매우 정교할 수 있습니다.

Garr ::= INTEGER (0..10 | 25..32)

이 책의 13장을 보십시오. PDF;당신이 할 수 있는 일은 정말 놀랍습니다.

배열도 제한될 수 있습니다.

Bar ::= SEQUENCE (SIZE(1..5)) OF Foo
Sna ::= SEQUENCE (SIZE(5)) OF Foo
Fee ::= SEQUENCE 
{
    boo SEQUENCE (SIZE(1..<6)) OF INTEGER (-180<..<180)
}

ASN.1은 구식이지만 여전히 적극적으로 개발되고 널리 사용되며(휴대폰에서 많이 사용됨) 대부분의 다른 직렬화 기술보다 훨씬 더 유연합니다.내가 볼 수 있는 유일한 결함은 Python용으로 괜찮은 코드 생성기가 없다는 것입니다.C/C++, C#, Java, ADA를 사용하는 경우 무료(C/C++, ADA) 도구와 상용(C/C++, C#, JAVA) 도구를 혼합하여 사용할 수 있습니다.

저는 특히 바이너리 및 텍스트 기반 와이어 형식을 선택할 수 있는 폭이 넓다는 점을 좋아합니다.이는 일부 프로젝트에서 매우 편리합니다.현재 와이어포맷 목록에는 다음이 포함됩니다.

  • BER(바이너리)
  • PER(이진, 정렬 및 정렬되지 않음.이것은 매우 효율적입니다.예를 들어 INTEGER는 다음과 같이 제한됩니다. 0 그리고 15 만 차지할 것이다 4 bits 전선에서)
  • OER
  • DER(또 다른 바이너리)
  • XML(또한 XER)
  • JSON(새로운 기능, 도구 지원은 아직 개발 중)

게다가 다른 사람들.

마지막 두 개를 기억하시나요?예, ASN.1에서 데이터 구조를 정의하고, 코드를 생성하고, XML 및 JSON으로 메시지를 내보내거나 사용할 수 있습니다.1980년대에 시작된 기술로는 나쁘지 않습니다.

버전 관리는 GPB와 다르게 수행됩니다.확장을 허용할 수 있습니다.

Foo ::= SEQUENCE
{
   bearing INTEGER (-180..180),
   ...
}

이는 나중에 추가할 수 있음을 의미합니다. Foo, 이 버전이 있는 이전 시스템은 계속 작동할 수 있습니다(그러나 bearing 필드).

나는 ASN.1을 매우 높이 평가합니다.처리하기가 어려울 수 있습니다(도구에는 비용이 들 수 있고, 생성된 코드가 반드시 아름다운 것은 아닙니다).그러나 제약 조건은 몇 번이고 나에게 엄청난 고통을 안겨준 정말 환상적인 기능입니다.인코더/디코더가 더프 데이터를 생성했다고 보고하면 개발자가 많이 징징거립니다.

기타 링크:

관찰

데이터를 공유하려면:

  • 코드 우선 접근 방식(예:부스트 직렬화)는 원래 언어로 제한합니다(예:C++) 또는 다른 언어로 많은 추가 작업을 수행하도록 강요합니다.
  • 스키마 우선이 더 좋지만
    • 이들 중 다수는 공유 계약에 큰 공백을 남깁니다(예:제약 없음).GPB는 이와 관련하여 짜증나는 일입니다. 그렇지 않으면 매우 훌륭하기 때문입니다.
    • 일부에는 제약이 있습니다(예:XSD, JSON)이지만 패치가 심한 도구 지원이 필요합니다.
    • 예를 들어, Microsoft의 xsd.exe는 xsd 파일의 제약 조건을 적극적으로 무시합니다(MS의 변명은 정말 미약합니다).제약 조건의 관점에서 XSD는 좋지만 다른 사람이 XSD를 시행하는 좋은 XSD 도구를 사용한다고 믿을 수 없다면 XSD의 가치는 감소합니다.
    • JSON 유효성 검사기는 괜찮지만 처음에 JSON을 구성하는 데 도움이 되지 않으며 자동으로 호출되지 않습니다.JSON 메시지를 보내는 사람이 유효성 검사기를 통해 메시지를 실행했다는 보장은 없습니다.스스로 검증해야 한다는 점을 기억해야 합니다.
    • ASN.1 도구는 모두 제약 조건 검사를 구현하는 것으로 보입니다.

그래서 저는 ASN.1이 그렇게 합니다.이는 올바른 기능을 갖추고 있고 모든 도구가 이러한 기능을 완전히 구현하려고 노력하는 것처럼 보이며 대부분의 목적에 대해 충분히 언어 중립적이기 때문에 다른 사람이 실수할 가능성이 가장 적은 것입니다.

솔직히 말해서, GPB가 제약 메커니즘을 추가한다면 승자가 될 것입니다.XSD는 가깝지만 도구는 거의 보편적으로 쓰레기입니다.다른 언어의 괜찮은 코드 생성기가 있다면 JSON 스키마는 꽤 좋을 것입니다.

GPB에 제약 조건이 추가된 경우(참고:이것은 유선 형식을 변경하지 않습니다.) 거의 모든 목적에 대해 모든 사람에게 권장하는 형식입니다.ASN.1의 uPER은 무선 링크에 매우 유용합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top