cgiosy.dev
압축 속도별 최적 알고리즘 본문
(아직 미완성인 글이다. 추후 더 정확히 벤치마크해서 자료를 추가할 예정.)
데이터를 통신 및 스트리밍할 때, 대역폭(IO나 네트워크 속도)보다 빠른 압축 알고리즘은 보통 필요치 않다. 이 글에선 사용례에 따라 잘 알려진 압축 알고리즘들을 분류해본다.
오라클 Ampere A1과 맥북 에어 M1 CPU를 기준으로 측정했다. 일반적인 클라우드의 CPU 성능은 이 사이에 존재하는 편이기에, 중간 정도의 값을 테스트해보고 결과에 따라 압축 수준을 낮추거나 높이도록 하자.
싱글 스레드를 기준으로 하며, 멀티 스레드의 경우 대역폭을 CPU의 물리 코어 수로 나눠서 보면 될 것 같다.
Disk I/O
읽기와 쓰기에 대한 대역폭이 제한된 것이므로, (원본 크기 + 압축 크기) / 소요 시간 / 1 MiB
을 기준으로 계산.
- 1000 MB/s:
lz4 1
-zstd 1
- 250 MB/s:
zstd 1 - 6
- 100 MB/s:
zstd 5 - 6
-brotli 5 - 6
네트워크
쓰기에 대한 대역폭이 제한된 것이므로, 압축 크기 / 소요 시간 / 1 MiB
을 기준으로 계산. 대역폭은 클라이언트 기준. 압축 후 크기는 원본의 1/3 정도임을 가정한다.
- 100 MB/s:
zstd 1 - 6
- 10 MB/s:
brotli 5 - 9
참고로 brotli 10 - 11
의 압축 속도는 아주 느리다. 미리 압축해두는 게 아닌, 실시간 압축에 10 이상을 적용하는 건 다시 생각해보는 것을 권한다.
아카이빙
압축 해제 속도가 압축 속도보다 크게 중요하다면 brotli 11
과 zstd 22
를, 그렇지 않다면 bsc와 lzma
도 고려해보자.
압축 해제 / 압축 속도 / 압축률이 좋은 것부터 나열하면 대충 다음과 같다.
- 압축 해제 속도:
zstd 22 > brotli 11 > lzma > bsc
- 압축 속도:
bsc > lzma >= zstd 22 > brotli 11
- 압축률:
bsc > brotli 11 > zstd 22 > lzma
- 사실 압축률은 매우 데이터 의존적이라 큰 의미는 없다.
bsc
는 다량의 글이 포함된 데이터에서 특히 강하다.brotli
는 소스 코드를 비롯한 다양한 파일에서 강하다.lzma
는 대체로 썩 좋지 않으나 가끔씩 가장 나은 압축률을 보여준다. 굳이 꼽자면 바이너리 계열에서 강세를 보이는 편이다.
개인적으로 평범한 파일에는 기능이 많고 무난한 성능을 보여주는 zstd 16 - 22
정도를 선호할 것 같다. 참고로 zstd는 멀티 스레딩, diff 추출, 간편한 사전 파일 생성, 파라미터 최적화용 툴 등의 훌륭한 기능과 편의성을 지니고 있다.
그 외
호환성 등의 이유로 불가피하게 zlib를 써야 한다면, libdeflate 나 cloudflare/zlib를 사용해보자. 레퍼런스 구현인 기존 zlib보다 최적화된 구현으로 잘 알려져 있다.
시간은 상관없고 그저 극한의 압축을 원한다면 paq8px, mcm 같은 걸 쓰거나, 아예 해당 데이터셋에 최적화된 특수 목적 압축 알고리즘을 찾아보는 것도 고려해보자.
메모
References
- GDCC - Global Data Compression Competition (2021)
- Sequence Compression Benchmark (2019 - 2022)
- TurboBench Compression Benchmark (2019)
- Squash Compression Benchmark (2018)
- encode.su - enwik8 benchmark (2020)
- 메아리 저널 - 압축 알고리즘 르네상스 1 (2017)
- 메아리 저널 - 압축 알고리즘 르네상스 2 (2017)