TECH 으로 돌아가기
TECH HACKER NEWS 6분 읽기 29 READS

순수 함수형 언어는 C에 얼마나 가까워질 수 있나 — Roc의 DEFLATE 실험

함수형 프로그래밍 언어가 과연 C로 작성된 고도로 튜닝된 라이브러리의 성능에 근접할 수 있을까. 이 오래된 질문에 대해 Roc 언어 진영에서 흥미로운 실측 결과가 나왔다. 발단은 'Why Lean is Faster Than Rust'라는 글이었다. 증명 보조 도구이자 함수형 언어인 Lean 4로 작성한 DEFLATE 압축 라이브러리 lean-zip이, crates.io 기준 10억 회 이상 다운로드된 Rust 패키지 miniz_oxide를 모든 압축 레벨에서 앞섰다는 내용이다. 가장 빠른 설정에서 15% 더 빠르면서 결과물은 8.8% 더 작았다. 다만 저자 스스로 인정하듯, 아키텍처별 SIMD로 세밀하게 최적화된 C 라이브러리 libdeflate 앞에서는 상대가 되지 못했다. Lean에서는 그런 하드웨어 밀착 기법에 손댈 수 없기 때문이다.

여기서 정리 증명 도구가 아니라 런타임 성능을 전면에 내세운 함수형 언어 Roc가 등장한다. Roc의 슬로건은 'Fast, Friendly, Functional'이고, 빠른 실행과 빠른 컴파일이 처음부터 핵심 목표였다. 아직 첫 번째 번호 릴리스인 0.1.0을 몇 주 앞둔 미성숙한 언어이고 패키지 생태계도 최적화가 거의 되지 않은 상태지만, 저자는 Roc가 'the champ' libdeflate에 도전할 기반은 갖췄다고 보고 Niclas Ahden이 작성해 유료 실무에 쓰고 있는 roc-deflate 패키지를 붙잡고 성능 최적화에 상당한 시간을 쏟았다.

한 자릿수 격차라는 결과

벤치마크는 고전적인 Silesia 코퍼스를 사용했고, 출력이 libdeflate와 바이트 단위로 동일한지 검증하면서 진행됐다. 2021년 M1 맥북 프로와 AMD 라이젠 9 3900X 우분투 머신에서 144개 벤치마크를 돌린 결과, roc-deflate는 평균적으로 libdeflate보다 느렸다. 중앙값 기준으로 라이젠에서 8.9%, M1에서 2.6% 느린 정도였다. 평균에서 챔피언을 이기지는 못했지만, SIMD로 무장한 정밀 튜닝 C 라이브러리를 상대로 한 자릿수 격차라는 것은 쉽게 나올 수 있는 숫자가 아니다. 자동 메모리 관리와 경계 검사를 수행하는 함수형 언어가, 그런 비용을 전혀 지불하지 않는 코드와 겨룬 결과라는 점에서 특히 그렇다.

분포를 보면 이야기가 더 선명해진다. 최악의 입력에서는 roc-deflate가 18% 느렸지만, 최선의 입력에서는 오히려 18%가량 빨랐다. 이는 Roc에 C가 접근할 수 없는 마법 같은 최적화가 있어서가 아니라, 두 구현이 서로 다른 방식이어서 특정 입력에서 우연히 유리하게 작동했을 뿐이다. 바꿔 말해 libdeflate에서 roc-deflate로 갈아타면 어떤 입력에서는 빨라질 수 있지만 평균적으로 그런 기대를 해서는 안 된다는 뜻이다. 저자도 분명히 선을 긋는다. C의 성능 천장은 Roc보다 높다. roc-deflate가 앞서는 입력이 있더라도 C 쪽은 그 격차를 메울 수 있지만, 반대는 성립하지 않는다. Roc 코드는 메모리 안전성, 자동 참조 카운팅, 경계 검사를 보장하며 Rust식 unsafe처럼 이를 빠져나갈 수단이 없다. 더 강한 안전 보장을 얻는 대가로 성능 천장이 낮은 것이다.

왜 조금 느린 것을 감수하나

자연스럽게 떠오르는 질문은 '그럴 거면 그냥 libdeflate를 쓰면 되지 않나'이다. 저자의 답은 역방향으로 명제를 뒤집어 보라는 것이다. 보장된 메모리 안전성, 부작용 없음, 모든 타깃에서의 결정론적 동작, 그리고 패키지에 악용 가능한 빌드 스크립트가 없다는 보안상의 이점을, 평균 한 자릿수의 속도 향상과 맞바꾸겠느냐는 것이다. roc-deflate 문서에 적힌 '100% 순수 함수'라는 문구는 이 모든 속성을 타입 시스템이 강제한다는 의미다. 물론 정답은 용도에 따라 달라진다. Roc 자체 컴파일러처럼 하드웨어가 낼 수 있는 최대 성능이 필요한 경우도 있다. 다만 경계 검사를 건너뛴 C 압축 코드가 심각한 원격 코드 실행 취약점으로 이어진 사례가 드물지 않다는 점은 균형추로 기억할 만하다.

실무자가 가져갈 Roc식 최적화 기법

성능 개선의 상당 부분은 언어를 가리지 않는 일반적인 최적화 기법에서 나왔지만, Roc 특유의 기법도 몇 가지 소개됐다. 첫째는 Koka가 'Functional but In-Place'라 부르는 기회적 변이(opportunistic mutation)다. 값이 유일하게 유지되어야 제자리 변이 대상이 되므로, 불필요한 공유를 피하는 것이 결정적으로 중요하다. 둘째, Roc에서는 경계 검사를 끌 수 없지만 컴파일러가 통과를 보장할 수 있으면 제거한다. 루프 내부의 경계 검사 비용이 크므로, 루프 시작 전에 'if collection.len()

SOURCE · HACKER NEWS
원문 전체 보기 → https://rtfeldman.com/fp-vs-c
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기 →
처리 중...