본문 바로가기

Unity/코드

C#에서 데이터를 압축하는 코드

유니티로 게임을 만지다 보면 데이터를 직접 압축할 일이 종종 생긴다.

특히 서버와 큰 데이터를 주고받거나 서버에서 굳이 열어보지 않을 데이터를 수집하는 등의 작업에서 압축을 하면 효과를 볼 때가 있다.

 

아래는 문자열을 압축하는 간단한 코드이다. 유니티서 사용할 경우 동기 버전으로 변형하거나 Task 대신 UniTask 등으로 변형해서 사용할 수 있다.

 

brotli compression in C#

brotli compression in C#. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

using System.IO;
using System.IO.Compression;
using System.Text;
using System.Threading.Tasks;

public static class Compression
{
    public static async Task<byte[]> Compress(string source)
    {
        var bytes = Encoding.UTF8.GetBytes(source);

        await using var input = new MemoryStream(bytes);
        await using var output = new MemoryStream();
        await using var brotliStream = new BrotliStream(output, CompressionLevel.Fastest);

        await input.CopyToAsync(brotliStream);
        await brotliStream.FlushAsync();

        return output.ToArray();
    }

    public static async Task<string> Decompress(byte[] compressed)
    {
        await using var input = new MemoryStream(compressed);
        await using var brotliStream = new BrotliStream(input, CompressionMode.Decompress);

        await using var output = new MemoryStream();

        await brotliStream.CopyToAsync(output);
        await brotliStream.FlushAsync();

        return Encoding.UTF8.GetString(output.ToArray());
    }
}

 

 


기타 압축에 대한 사소한 정보들

  1. brotli는 구글에서 개발한 압축 알고리즘으로, 특히 텍스트 데이터에 일반적으로 gzip보다 빠르고 압축률이 좋다.
  2. C#의 ZLibStream, GZipStream은 각각 zlib(RFC-1950), gzip(RFC-1952) 형식을 구현한다. zlib 및 gzip은 압축에 사용하는 알고리즘을 선택할 수 있도록 되어 있는데, 일반적으로, 그리고 C#의 구현에서도 deflate를 사용한다
  3. DeflateStream은 deflate 알고리즘(RFC-1951) 을 구현한다.
  4. 위의 코드는 비동기 버전으로 작성되어 있지만, 일반적으로 몇KB 정도는 게임 도중 아무때나, 몇백KB까지도 적당한 UI와 함께라면 동기식으로 실행해도 거의 끊김이나 어색함을 느낄 수 없다.
  5. brotli는 압축 해제는 매우 빠르지만, CompressionLevel.Optimal 옵션으로 압축을 할 경우 매우 느리다. 클라이언트에서 압축을 해야 하는 경우 CompressionLevel.Fastest를 사용하는 편이 좋다.
  6. 주의: 유니티에서 실행할 경우, BrotliStream은 비동기 버전으로 실행해도 동기식처럼 작동한다. 기본 SynchronizationContext가 제공하는 병렬처리 기능에 의존하기 때문이다. DeflateStream는 그렇지 않기 때문에 비동기+병렬로 작동한다. 
 

유니티에서 async/await를 어떻게 쓰면 좋을까?

async/await는 비동기? 병렬? C#의 async/await와 Task는 비동기를 표현한 것일까 병렬실행을 표현한 것일까? 이 점을 헷갈려하는 사람들이 아주 많다. 결론부터 말하면 Task는 비동기 작업을 표현하는 클

tearsinrain.tistory.com

 

'Unity > 코드' 카테고리의 다른 글

코루틴 여러개가 모두 완료될때까지 대기하는 코드  (0) 2024.02.20