본문 바로가기

Unity

유니티에서 테이블 데이터 로드하기 #4 - Source Generator

C#의 Source Generator를 사용하여 직렬화/역직렬화 코드를 생성하는 방법도 있다.

 

이론적으로 어떤 클래스를 byte array로 변환하려면 각 멤버를 모두 개별적으로 BitConverter 등을 이용해서 순서대로 byte array에 쓰면 되는데, 모든 데이터를 표현하는 클래스에 개별적으로 직렬화하는 코드를 작성하는 방법은 현실적이지 않다.

하지만 C#에는 이럴 때 사용할 수 있는 기능이 있는데, 바로 Source Generator이다.

https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview

 

Source Generators

Source Generators is a C# compiler feature that lets C# developers inspect user code as it is being compiled. Source generators create new C# source files on the fly that are added to the user's compilation.

learn.microsoft.com

 

Source Generator는 컴파일타임에 소스를 분석해서 소스를 추가할 수 있도록 해준다. C++등의 타 언어에서 가끔 반복적이고 기계적인 코드 작성을 자동화하기 위해, 소스코드를 단순한 텍스트 파일로서 간주하여 나름대로 분석, 변환, 추가 등을 하려는 시도를 할 때가 있다. C#은 그런 기능을 언어차원에서 지원하고 있어서 훨씬 쉽고 간단하게, 또 안정적으로 만들 수 있다.

 

Source Generator의 자세한 사용법은 글의 범위를 벗어나서 여기다 사용법을 모두 적지는 않는다. 대신 쉽게 사용할 수 있는 Source Generator 기반 범용 직렬화 라이브러리를 하나 소개한다.

 

UniTask, MagicOnion등으로 유명한 Cysharp에서 만든 MemoryPack이다.

https://github.com/Cysharp/MemoryPack/

 

GitHub - Cysharp/MemoryPack: Zero encoding extreme performance binary serializer for C# and Unity.

Zero encoding extreme performance binary serializer for C# and Unity. - GitHub - Cysharp/MemoryPack: Zero encoding extreme performance binary serializer for C# and Unity.

github.com

 

기본 형식과 문자열, 컬렉션들까지 지원하며 확장 가능한 범용 직렬화 라이브러리이며 고성능이다. 단순히 테이블 데이터와 같은 2차원 배열에 한정한다면, 더욱 고성능인 코드를 만들 수도 있을 것 같다. 종합적으로 볼 때, 개발 및 유지보수의 관점을 제외하고 단순히 성능만 놓고 본다면 정답이라고 할 수 있는 방식이다.

 


장점

  1. 파싱이 빠르다. MemoryPack 기준으로 json에 비해 10~15배 가량 빠르며, 아마도 이론적으로는 이것보다 더 빠르게 읽어오는 방법은 없을 것 같다.
  2. json이나 csv등과 비교하면 파싱을 위한 태그 등이 없으므로 데이터 크기가 작다.
  3. 컴파일 타임에 소스 코드가 추가되는 것이므로 IOS의 동적 코드 생성 제한 등의 문제에서 자유롭다.

단점

  1. Source Generator 자체가 생소하여 학습 및 적용에 약간 어려움이 있을 수 있다.
  2. 직접 개발할 경우 개발 및 디버그/유지보수가 어려울 수 있다.