한국정보기술진흥원
한국정보기술신문
thumbnail

정보기술 ·

파이썬 패키지 매니저 uv, 속도의 비밀은 '러스트'가 아니었다...표준화와 최적화가 핵심

발행일
읽는 시간2분 45초

정적 메타데이터와 불필요한 기능 제거로 pip 대비 10배 빠른 설치 속도 구현

[한국정보기술신문] 파이썬 패키지 매니저 uv가 기존 pip보다 10배 이상 빠른 패키지 설치 속도를 보이며 개발자 커뮤니티의 주목을 받고 있다. 많은 이들이 uv의 속도를 러스트 언어로 작성되었기 때문이라고 설명하지만, 실제 핵심은 설계 결정과 파이썬 생태계의 표준화에 있는 것으로 분석됐다.

앤드류 네스빗은 지난 26일 자신의 블로그를 통해 uv의 속도 비결을 상세히 분석한 글을 게재했다. 그는 찰리 마쉬의 제인 스트리트 강연과 젭시아 엔지니어링의 심층 분석을 인용하며, uv의 성능 향상이 단순히 프로그래밍 언어 선택의 문제가 아니라고 강조했다.

파이썬 표준의 진화가 만든 가능성

pip의 느린 속도는 구현 실패가 아니라 파이썬 패키징 시스템의 구조적 문제에서 비롯됐다. 수년간 파이썬 패키징은 패키지가 무엇을 필요로 하는지 알아내기 위해 코드를 실행해야 했다. setup.py 파일을 실행하지 않고는 패키지의 의존성을 알 수 없었지만, setup.py를 실행하려면 빌드 의존성을 먼저 설치해야 하는 순환 문제가 존재했다.

이 문제는 2016년부터 2022년까지 단계적으로 해결됐다. 2016년 PEP 518은 pyproject.toml을 도입해 코드 실행 없이 빌드 의존성을 선언할 수 있게 했다. 2017년 PEP 517은 빌드 프론트엔드와 백엔드를 분리했으며, 2020년 PEP 621은 프로젝트 테이블을 표준화해 파이썬 실행 대신 TOML 파싱으로 의존성을 읽을 수 있게 했다.

결정적으로 2022년 PEP 658은 패키지 메타데이터를 심플 리포지토리 API에 직접 포함시켜, 휠 파일을 다운로드하지 않고도 의존성 정보를 가져올 수 있게 했다. PEP 658은 2023년 5월 PyPI에 적용됐고, uv는 2024년 2월 출시됐다. 이 타이밍은 우연이 아니다. uv가 빠를 수 있었던 것은 생태계가 마침내 이를 지원할 인프라를 갖췄기 때문이다.

속도는 제거에서 나온다

uv는 pip이 지원하는 많은 기능을 의도적으로 제외했다. 10년 넘게 사용되지 않는 egg 형식 지원을 없앴고, pip의 설정 파일을 완전히 무시한다. 기본적으로 바이트코드 컴파일을 건너뛰며, 가상 환경을 필수로 요구해 시스템 파이썬 설치를 거부한다.

특히 주목할 만한 최적화는 requires-python 상한선 무시다. 패키지가 python 4.0 미만을 요구한다고 선언할 때, uv는 상한선을 무시하고 하한선만 확인한다. 이는 패키지 개발자들이 파이썬 4에서 테스트하지 않았다는 이유로 방어적으로 설정한 제약이지, 실제로 작동하지 않을 것이라는 예측이 아니기 때문이다. 이로써 의존성 해결 백트래킹이 극적으로 감소한다.

러스트 없이도 가능한 최적화들

uv 속도 향상의 상당 부분은 러스트가 아니어도 구현 가능한 최적화에서 나온다. HTTP 범위 요청을 통한 메타데이터 추출, 병렬 다운로드, 하드링크를 활용한 전역 캐시, 파이썬 없는 의존성 해결, PubGrub 알고리즘 사용 등이 대표적이다.

휠 파일은 zip 아카이브이며, zip 아카이브는 파일 목록을 끝에 배치한다. uv는 먼저 PEP 658 메타데이터를 시도하고, 실패하면 HTTP 범위 요청으로 zip 중앙 디렉토리만 가져오며, 그래도 안 되면 전체 휠을 다운로드하고, 마지막으로 소스에서 빌드한다. 이러한 단계적 접근으로 99%의 경우를 빠른 경로로 처리한다.

pip은 패키지를 하나씩 다운로드하지만 uv는 여러 개를 동시에 다운로드한다. pip은 각 가상 환경에 패키지를 복사하지만 uv는 전역 캐시에 하나만 보관하고 하드링크를 사용한다. 같은 패키지를 10개 가상 환경에 설치해도 디스크 공간은 하나만 차지한다.

러스트가 실제로 중요한 부분

일부 최적화는 러스트를 필요로 한다. rkyv를 사용한 제로카피 역직렬화, 소유권 모델을 통한 락 프리 동시성 데이터 구조, 인터프리터 시작 비용 제거, u64 정수로 압축된 버전 표현 등이다. 하지만 이러한 이점은 레거시 지원을 제거하고 현대 표준을 활용한 아키텍처적 승리에 비하면 작다.

네스빗은 "pip도 병렬 다운로드, 전역 캐싱, 메타데이터 전용 해결을 내일 당장 구현할 수 있다. 하지만 15년간 축적된 엣지 케이스와의 하위 호환성이 우선순위를 차지하기 때문에 그렇게 하지 않는다"고 지적했다.

그는 다른 패키지 매니저들을 위한 교훈으로 "uv를 빠르게 만드는 것은 정적 메타데이터, 의존성 발견을 위한 코드 실행 배제, 다운로드 전 모든 것을 미리 해결할 수 있는 능력"이라고 강조했다. 러스트의 카고와 자바스크립트의 npm은 이미 수년간 이런 방식으로 작동해왔다. 만약 당신의 생태계가 패키지가 무엇을 필요로 하는지 알아내기 위해 임의의 코드를 실행해야 한다면, 이미 경쟁에서 뒤처진 것이라는 게 그의 결론이다.

한국정보기술신문 정보통신분과 문창우 기자 news@kitpa.org