Programing

.NET에서 빠르고 간결한 개체 직렬화

lottogame 2020. 12. 14. 07:45
반응형

.NET에서 빠르고 간결한 개체 직렬화


Mono 서버와 Silverlight 클라이언트 간의 네트워크를 통해 통신하기 위해 개체 직렬화를 사용하고 싶습니다 . 서버가 여러 실시간 게임을 호스팅 할 것이므로 직렬화가 공간 효율적이고 매우 빠르다는 것은 매우 중요합니다.

어떤 기술을 사용해야합니까? BinaryFormatter는이 응용 프로그램 내에서 필요하지 않은 직렬화 된 클래스 (버전, 문화권, 클래스 이름, 속성 이름 등)에 많은 오버 헤드를 추가합니다.

이 공간을 더 효율적으로 만들려면 어떻게해야합니까?


프로토콜 버퍼 를 사용할 수 있습니다 . 압축을 사용하여 BinaryFormatter에서 프로토콜 버퍼로 모든 직렬화 코드를 변경하고 매우 좋은 결과를 얻고 있습니다. 시간과 공간 모두에서 더 효율적입니다.

Jon SkeetMarc Gravell의 두 가지 .NET 구현이 있습니다 .

업데이트 : 공식 .NET 구현은 여기 에서 찾을 수 있습니다 .


나는 몇 가지가 주요 .NET 시리얼 라이저에 대한 벤치 마크 에서는 Northwind 데이터 세트에 따라 사용할 수 있습니다.

Northwind .NET 직렬화 벤치 마크

@marcgravell 바이너리 protobuf-net은 BCL에서 사용 가능한 Microsoft 가장 빠른 직렬 변환기 (XML DataContractSerializer)보다 7 배 빠른 벤치 마크 된 가장 빠른 구현 입니다.

또한 일부 오픈 소스 고성능 .NET 텍스트 시리얼 라이저도 유지합니다.

  • JSV TypeSerializer 는 DataContractSerializer보다 3.1 배 빠른 컴팩트하고 깨끗한 JSON + CSV 형식입니다.
  • 뿐만 아니라 JsonSerializer 빠른 2.6 배를합니다.

저자로서 protobuf-net 을 사용해 보도록 권합니다 . Mono 2.0 및 Silverlight 2.0 용 바이너리와 함께 제공되며 빠르고 효율적 입니다. 문제가 있으면 이메일을 보내주세요 (Stack Overflow 프로필 참조). 지원은 무료입니다.

Jon의 버전 (이전 승인 된 답변 참조)도 매우 좋지만 IMO protobuf-net 버전은 C #에 더 관용적입니다 .Jon의 버전은 C #과 Java를 사용하는 경우 이상적이므로 양쪽에서 유사한 API를 사용할 수 있습니다.


.NET을 사용하고 있지만 비슷한 문제가 발생했습니다. 가능한 한 빠르고 쉽게 인터넷을 통해 데이터를 보내고 싶었습니다. 충분히 최적화 될 수있는 것을 찾지 못해서 NetSerializer 라는 자체 직렬 변환기를 만들었습니다 .

NetSerializer에는 한계가 있지만 사용 사례에는 영향을 미치지 않았습니다. 그리고 나는 한동안 벤치 마크를하지 않았지만 내가 찾은 어떤 것보다 훨씬 빠르다.

Mono 또는 Silverlight에서 시도한 적이 없습니다. Mono에서 작동한다고 확신하지만 Silverlight의 DynamicMethods에 대한 지원 수준이 무엇인지 잘 모르겠습니다.


JSON을 사용해 볼 수 있습니다. 프로토콜 버퍼만큼 대역폭 효율적이지는 않지만 Wireshark와 같은 도구를 사용하여 메시지를 모니터링하는 것이 훨씬 쉬울 것입니다. 이는 문제를 디버깅 할 때 많은 도움이됩니다. .NET 3.5는 JSON 직렬 변환기와 함께 제공됩니다.


You could pass the data through a DeflateStream or GZipStream to compress it prior to transmission. These classes live in the System.IO.Compression namespace.


I had a very similar problem - saving to a file. But the following can also be used over a network as it was actually designed for remoting.

The solution is to use Simon Hewitt's library - see Optimizing Serialization in .NET - part 2.

Part 1 of the article states (the bold is my emphasis): "... If you've ever used .NET remoting for large amounts of data, you will have found that there are problems with scalability. For small amounts of data, it works well enough, but larger amounts take a lot of CPU and memory, generate massive amounts of data for transmission, and can fail with Out Of Memory exceptions. There is also a big problem with the time taken to actually perform the serialization - large amounts of data can make it unfeasible for use in apps ...."

I got a similar result for my particular application, 40 times faster saving and 20 times faster loading (from minutes to seconds). The size of the serialised data was also much reduced. I don't remember exactly, but it was at least 2-3 times.

It is quite easy to get started. However there is one gotcha: only use .NET serialisation for the very highest level datastructure (to get serialisation/deserialisation started) and then call the serialisation/deserialisation functions directly for the fields in the highest level datastructure. Otherwise there will not be any speed-up... For instance, if a particular data structure (say Generic.List) is not supported by the library then .NET serialisation will used instead and this is a no-no. Instead serialise the list in client code (or similar). For an example see near "'This is our own encoding." in the same function as listed below.

For reference: code from my application - see near "Note: this is the only place where we use the built-in .NET ...".


패킹 된 데이터 크기에 초점을 맞추고 지금까지 최고의 패킹을 제공하는 BOIS를 사용해 볼 수 있습니다. (아직 더 나은 최적화를 보지 못했습니다.)

https://github.com/salarcode/Bois

참고 URL : https://stackoverflow.com/questions/549128/fast-and-compact-object-serialization-in-net

반응형