uv의 교훈과 Rust 재작성 논의
uv의 속도 비결은 Rust 언어 자체보다는 백워드 호환성 제약 없는 새로운 설계 채택에 있습니다. Bundler는 Rust 재작성 없이 기존 Ruby 코드베이스 내에서 병목을 제거하여 uv에 준하는 성능 향상을 목표로 합니다. RubyGems는 젬 메타데이터를 즉시 파싱할 수 있으며, uv처럼 Ruby 버전 상한 검사를 최적화할 여지가 있습니다.
Bundler/RubyGems 성능 개선 핵심 방안
- 병렬 다운로드 및 설치 과정 분리:
- 현재 Bundler는 젬 다운로드와 설치가 결합되어 의존성 체인에서 순차 처리됩니다. 이를 다운로드, 압축 해제, 컴파일, 설치의 4단계로 분리하여 다운로드 및 압축 해제를 병렬로 수행합니다. 순수 Ruby 젬은 의존성 순서 제약을 완화하여 병렬화를 극대화하고, 네이티브 확장 젬은 의존성 설치 후 컴파일합니다.
- 전역 캐시 및 하드링크 도입:
- Ruby 버전별로 분리된 캐시 대신
$XDG_CACHE_HOME에 통합된 전역 캐시를 구축하고, 젬 설치 시 하드링크를 활용하여 중복 복사를 방지합니다.
- Ruby 버전별로 분리된 캐시 대신
- PubGrub 리졸버 통일:
- Bundler와 RubyGems가 다른 리졸버를 사용하는 이원화를 해소하고, 코드베이스 통합을 통해 단일 리졸버를 사용해야 합니다.
Ruby GVL과 버전 표현 최적화
Ruby의 GVL은 IO 바운드 작업 및 GVL을 해제하는 네이티브 확장 코드의 병렬 실행을 허용하므로, 젬 설치 과정에서 큰 문제가 되지 않습니다. uv가 버전을 u64 정수로 압축하여 비교 속도를 높이듯이, Ruby에서도 버전을 정수 즉치로 인코딩하여 리졸버 성능을 향상시킬 수 있으며, YJIT/ZJIT를 통해 Rust 구현체와의 성능 격차를 줄일 수 있습니다.