문제

다가오는 프로젝트를 위해 일부 캐싱을 생각하고 있으며 Java 직렬화에 대해 생각하고 있습니다.즉, 사용해야 하는가?

이제 저는 이전에 여러 가지 이유로 사용자 지정 직렬화 및 역직렬화(외부화 가능)를 작성했습니다.요즘 상호 운용성은 훨씬 더 큰 문제가 되었고 .Net 응용 프로그램과 상호 작용해야 할 필요성이 예상되어 플랫폼 독립적인 솔루션을 사용하는 것을 고려했습니다.

GPB를 고성능으로 사용해 본 경험이 있는 사람이 있습니까?속도와 효율성 측면에서 Java의 기본 직렬화와 어떻게 비교됩니까?아니면 고려해 볼 만한 다른 계획이 있나요?

도움이 되었습니까?

해결책

프로토콜 버퍼를 Java의 원시 직렬화와 속도 측면에서 비교하지는 않았지만 상호 운용성의 경우 Java의 원시 직렬화는 심각한 무의미입니다. 또한 대부분의 경우 프로토콜 버퍼만큼 공간 측면에서 효율적이지 않을 것입니다. 물론, 저장할 수있는 측면에서, 참조 등의 관점에서 다소 유연합니다. 프로토콜 버퍼는 의도 한 내용에 매우 능숙하며 필요에 맞는시기는 훌륭하지만 상호 운용성으로 인한 명백한 제한 사항이 있습니다. (및 다른 것들).

최근에 Java 및 .NET에 프로토콜 버퍼 벤치마킹 프레임 워크를 게시했습니다. Java 버전이 있습니다 주요 Google 프로젝트 (에서 벤치 마크 디렉토리), .NET 버전이 있습니다 내 C# 포트 프로젝트. PB 속도를 Java 직렬화 속도와 비교하려면 유사한 클래스를 작성하고 벤치마킹 할 수 있습니다. 그러나 Interop에 관심이 있다면, 나는 Native Java 직렬화 (또는 .Net Native Binasy Serialization)에게 두 번째 생각을주지 않을 것입니다.

프로토콜 버퍼 외에 상호 운용 가능한 직렬화를위한 다른 옵션이 있습니다. 절약, JSON 그리고 봄이 떠오르고 의심 할 여지없이 다른 사람들이 있습니다.

편집 : 좋아요, 인터 로프가 중요하지 않으면 직렬화 프레임 워크에서 원하는 다양한 품질을 나열하려고 노력할 가치가 있습니다. 당신이 생각해야 할 한 가지는 버전싱입니다. 이것은 PB가 뒤쪽 및 앞으로 잘 처리하도록 설계된 또 다른 것입니다 (따라서 새로운 소프트웨어는 이전 데이터를 읽을 수 있고 그 반대도 마찬가지입니다.

Java Performance vs Native Serialization에 대해 신중하려고 노력하면서, PB가 어쨌든 더 빠른다는 사실에 놀라지 않을 것입니다. 기회가 있다면 서버 VM을 사용합니다. 최근 벤치 마크가 서버 VM을 보여주었습니다. 두 배 이상 샘플 데이터를 직렬화하고 실조시킬 때. PB 코드가 서버 VM의 JIT에 아주 잘 맞는다 고 생각합니다 :)

샘플 성능 수치, 두 개의 메시지 (128 바이트, 84750 바이트 1 개)를 직렬화 및 탈선시킵니다. 서버 vm을 사용하여 랩톱 에서이 결과를 얻었습니다.

Benchmarking benchmarks.GoogleSize$SizeMessage1 with file google_message1.dat 
Serialize to byte string: 2581851 iterations in 30.16s; 18.613789MB/s 
Serialize to byte array: 2583547 iterations in 29.842s; 18.824497MB/s 
Serialize to memory stream: 2210320 iterations in 30.125s; 15.953759MB/s 
Deserialize from byte string: 3356517 iterations in 30.088s; 24.256632MB/s 
Deserialize from byte array: 3356517 iterations in 29.958s; 24.361889MB/s 
Deserialize from memory stream: 2618821 iterations in 29.821s; 19.094952MB/s 

Benchmarking benchmarks.GoogleSpeed$SpeedMessage1 with file google_message1.dat 
Serialize to byte string: 17068518 iterations in 29.978s; 123.802124MB/s 
Serialize to byte array: 17520066 iterations in 30.043s; 126.802376MB/s 
Serialize to memory stream: 7736665 iterations in 30.076s; 55.93307MB/s 
Deserialize from byte string: 16123669 iterations in 30.073s; 116.57947MB/s 
Deserialize from byte array: 16082453 iterations in 30.109s; 116.14243MB/s
Deserialize from memory stream: 7496968 iterations in 30.03s; 54.283176MB/s 

Benchmarking benchmarks.GoogleSize$SizeMessage2 with file google_message2.dat 
Serialize to byte string: 6266 iterations in 30.034s; 16.826494MB/s 
Serialize to byte array: 6246 iterations in 30.027s; 16.776697MB/s 
Serialize to memory stream: 6042 iterations in 29.916s; 16.288969MB/s 
Deserialize from byte string: 4675 iterations in 29.819s; 12.644595MB/s 
Deserialize from byte array: 4694 iterations in 30.093s; 12.580387MB/s 
Deserialize from memory stream: 4544 iterations in 29.579s; 12.389998MB/s 

Benchmarking benchmarks.GoogleSpeed$SpeedMessage2 with file google_message2.dat 
Serialize to byte string: 39562 iterations in 30.055s; 106.16416MB/s 
Serialize to byte array: 39715 iterations in 30.178s; 106.14035MB/s 
Serialize to memory stream: 34161 iterations in 30.032s; 91.74085MB/s 
Deserialize from byte string: 36934 iterations in 29.794s; 99.98019MB/s 
Deserialize from byte array: 37191 iterations in 29.915s; 100.26867MB/s 
Deserialize from memory stream: 36237 iterations in 29.846s; 97.92251MB/s 

"속도"대 "크기"는 생성 된 코드가 속도 또는 코드 크기에 최적화되어 있는지 여부입니다. (직렬화 된 데이터는 두 경우 모두 동일합니다. "크기"버전은 많은 메시지가 정의되어 있고 코드에 대한 많은 메모리를 가져오고 싶지 않은 경우에 제공됩니다.)

보시다시피, 작은 메시지를 위해 매우 빠른 - 500 개가 넘는 작은 메시지 직렬화 또는 사형화 밀리 초당. 87K 메시지가 있더라도 메시지 당 1 밀리 초 미만이 걸립니다.

다른 팁

하나 더 데이터 포인트 :이 프로젝트 :

http://code.google.com/p/thrift-protobuf-compare/

PB의 Java 직렬화를 포함하여 작은 개체에 대한 예상 성능에 대한 아이디어를 제공합니다.

결과는 플랫폼에 따라 다르지만 몇 가지 일반적인 추세가 있습니다.

당신은 또한 볼 수 있습니다 FST, 더 빠르고 더 작은 출력을 가져야 하는 내장 JDK 직렬화에 대한 드롭인 대체품입니다.

최근 몇 년 동안 자주 수행한 벤치마킹에 대한 원시 추정:

100% = 바이너리/구조체 기반 접근 방식(예:SBE, fst-구조체)

  • 불편한
  • 후처리(수신자 측에서 "실제" 객체 구축)는 성능 이점을 약화시킬 수 있으며 벤치마크에 포함되지 않습니다.

~10%-35% protobuf 및 파생물

FST 및 KRYO와 같은 ~10%-30% 빠른 직렬 변환기

  • 편리하고 역직렬화된 개체는 추가 수동 번역 코드 없이 직접 사용할 수 있는 경우가 가장 많습니다.
  • 성능을 위해 포주할 수 있음(주석, 클래스 등록)
  • 객체 그래프의 링크 유지(두 번 직렬화된 객체 없음)
  • 순환 구조를 처리할 수 있음
  • 일반 솔루션인 FST는 JDK 직렬화와 완벽하게 호환됩니다.

~2%-15% JDK 직렬화

~1%-15% 빠른 JSON(예:잭슨)

  • 어떤 객체 그래프도 처리할 수 없지만 Java 데이터 구조의 작은 하위 집합만 처리할 수 있습니다.
  • 참조 복원 없음

0.001-1% 전체 그래프 JSON/XML(예:JSON.io)

이 숫자는 매우 대략적인 크기의 인상을 주기 위한 것입니다.성능은 직렬화/벤치마킹되는 데이터 구조에 따라 크게 달라집니다.따라서 단일 단순 클래스 벤치마크는 대부분 쓸모가 없습니다(하지만 널리 사용됩니다:예를 들어유니코드 무시, 컬렉션 없음, ..).

또한보십시오

http://java-is-the-new-c.blogspot.de/2014/12/a-pertant-keyvalue-server-in-40.html

http://java-is-the-new-c.blogspot.de/2013/10/still-using-externalised-to-get.html

속도와 효율성에 대한 PB와 Native Java 직렬화를 혼동하고 있다면 PB로 이동하십시오.

  • PB는 그러한 요인을 달성하도록 설계되었습니다. 보다 http://code.google.com/apis/protocolbuffers/docs/overview.html
  • PB 데이터는 매우 작고 Java 직렬화는 서명을 포함하여 전체 객체를 복제하는 경향이 있습니다. 왜 수신기 이름, 필드 이름 ... 직렬화, 수신기에서 내부를 알고 있지만 왜 직렬화됩니까?
  • 언어 개발에 대해 생각하십시오. 한쪽이 Java를 사용하면 한쪽은 C ++를 사용하면 힘들어지고 있습니다.

일부 개발자는 중고품을 제안하지만 "Google을 믿는다":-) .. 어쨌든, 볼 가치가 있습니다.http://stuartsierra.com/2008/07/10/thrift-vs-protocol-buffers

고성능이란 무엇을 의미합니까? milli-second 직렬화를 원한다면 가장 간단한 직렬화 접근법을 사용하는 것이 좋습니다. 하위 milli-second를 원한다면 이진 형식이 필요할 수 있습니다. 10 마이크로 초 미만을 원한다면 사용자 정의 직렬화가 필요할 수 있습니다.

나는 직렬화/사막화를위한 많은 벤치 마크를 보지 못했지만 직렬화/사제 화를 위해 200 마이크로 초 미만의 지원은 거의 없습니다.

플랫폼 독립 형식은 비용으로 (귀하의 측면 및 대기 시간에 따라) 성능 또는 플랫폼 독립성을 원하는지 여부를 결정해야 할 수도 있습니다. 그러나 필요에 따라 사이를 전환 할 구성 옵션으로 둘 다 가질 수없는 이유는 없습니다.

여기 오늘의 벽 제안이 있습니다 :-) (당신은 내가 지금 시도하고 싶은 내 머리에 무언가를 조정했습니다) ...

이를 통해 전체 캐싱 솔루션을 찾을 수 있다면 다음과 같습니다. Darkstar 프로젝트. 매우 고성능 게임 서버, 특히 읽기가 빠르도록 설계되었습니다 (캐시에 좋습니다). 그것은 Java와 C API를 가지고 있기 때문에 나는 당신이 Java로 물체를 저장하고 C에서 다시 읽을 수 있다고 생각하지 않았다고 생각합니다 (내가 이것을보고 한 지 오래되었다고 생각했습니다.

다른 것이 없다면 오늘 읽을 무언가를 줄 것입니다 :-)

유선 친화적인 직렬화를 위해서는 외부화 가능 인터페이스 사용을 고려하십시오.현명하게 사용하면 특정 필드를 최적으로 마샬링 및 언마샬링하는 방법을 결정할 수 있는 친밀한 지식을 갖게 됩니다.즉, 각 개체의 버전 관리를 올바르게 관리해야 합니다. 비마샬링은 쉽지만 코드가 V1을 지원할 때 V2 개체를 다시 마샬링하면 앱이 손상되거나 정보가 손실되거나 더 심각한 방식으로 데이터가 손상될 수 있습니다. 제대로 처리할 수 없습니다.최적의 경로를 찾고 있다면 타협 없이는 어떤 라이브러리도 문제를 해결할 수 없다는 점에 유의하세요.일반적으로 라이브러리는 대부분의 사용 사례에 적합하며 활성 오픈 소스 프로젝트를 선택한 경우 사용자의 입력 없이 시간이 지남에 따라 적응하고 향상되는 추가 이점이 제공됩니다.그리고 성능 문제를 추가하고, 버그를 도입하고, 아직 영향을 미치지 않은 버그를 수정할 수도 있습니다!

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