2025년 새해를 맞아 YJIT 팀은 Ruby 3.4와 함께 더욱 빠르고 안정적이며 메모리 효율적인 YJIT 3.4를 선보입니다. 과거 YJIT의 성능은 주로 CRuby 인터프리터와의 비교를 통해 강조되었으나, 이제 많은 프로덕션 환경에서 YJIT가 기본으로 활성화되어 있다는 점을 고려하여, YJIT 3.4는 이전 버전인 YJIT 3.3.6과의 비교에 초점을 맞추고 있습니다. 이는 인터프리터 성능 저하가 YJIT를 과대평가하게 만드는 상황을 방지하고, 실제 업그레이드 시 사용자가 체감할 수 있는 개선 사항을 명확히 보여주기 위함입니다. 이번 릴리스는 다양한 내부 최적화와 사용자 편의성 개선을 포함하며, Ruby 생태계 전반에 긍정적인 영향을 미칠 것으로 기대됩니다.
YJIT 3.4는 벤치마크에서 YJIT 3.3.6 대비 5~7%의 성능 향상을 달성했습니다. 이는 폭발적인 수치는 아니지만, 많은 사용 사례에서 눈에 띄는 속도 개선을 가져올 수 있습니다. 더불어 상당한 메모리 사용량 감소와 다양한 버그 수정, 그리고 일부 편의성 개선이 함께 이루어졌습니다.
주요 개선 사항으로는 메모리 할당 설정 옵션 --yjit-mem-size=N
도입, YJIT 컴파일 로그 --yjit-log
추가, perf
도구를 사용한 프로파일링 지원 강화 등이 있습니다. 특히 컴파일 로그는 프로덕션 환경에서 동적으로 컴파일되는 코드를 모니터링하는 데 유용합니다.
성능 향상의 상당 부분은 개선된 인라이닝 기능에서 비롯됩니다. String#empty?
, Array#length
와 같은 핵심 C 메서드뿐만 아니라, 비어 있는 메서드, 상수를 반환하는 메서드, self
나 인수를 직접 반환하는 간단한 Ruby 메서드에 대한 인라이닝 지원이 강화되었습니다. 이를 통해 lobsters
벤치마크에서 C 메서드 호출의 56.3%, Ruby 호출의 4.8%를 인라이닝하고, liquid-render
벤치마크에서는 C 메서드 호출의 82.5%, Ruby 호출의 7.6%를 인라이닝할 수 있게 되었습니다. 이는 Sorbet 타입 어노테이션 성능 향상에도 도움이 됩니다.
C와 Ruby 코드 간의 호출 오버헤드를 줄이기 위해 Array#each
, Array#map
, Array#select
, Array#filter
, Integer#downto
등 특정 코어 메서드의 구현을 YJIT 활성화 시에만 순수 Ruby 버전으로 전환하는 기능이 추가되었습니다. 이를 통해 인터프리터 성능 저하 없이 YJIT의 최적화 효과를 극대화할 수 있습니다.
바이너리 직렬화 성능 개선도 중요한 특징입니다. String#setbyte
, String#getbyte
, String#<<
(바이너리 문자열에 바이트 추가), 새로운 String#append_as_bytes
메서드에 대한 YJIT 패스트 패스가 추가되었으며, 비트 연산 지원도 개선되었습니다. 이를 통해 순수 Ruby로 작성된 바이너리 데이터 처리 코드가 Ruby 3.3 대비 약 14% 빨라졌습니다.
또한, Array
, Hash
, String
과 같은 클래스 타입 정보 전파 개선, 로컬 변수 및 인수에 대한 레지스터 할당 기능이 향상된 레지스터 할당기, 예외 발생 가능성이 있는 C 함수 호출 시 스택 프레임 푸싱을 필요한 경우에만 지연시키는 Lazy frame pushing 기법 등 다양한 내부 최적화가 적용되었습니다.
메모리 사용량 측면에서 YJIT 3.4는 YJIT 3.3보다 평균적으로 적은 메모리를 사용합니다. 이는 CRuby 자체의 메모리 관리 개선(예: 스택 공간 지연 할당)과 YJIT 내부의 압축된 컨텍스트 표현, 중복 메타데이터 제거 등의 노력 덕분입니다. 벤치마크 결과, YJIT 3.4는 대부분의 벤치마크에서 YJIT 3.3보다 빠르면서도 메모리 사용량은 감소했습니다.
Shopify 프로덕션 환경, 특히 StoreFront Renderer(SFR) 서버에서의 성능 측정 결과도 긍정적입니다. Ruby 3.4.0 인터프리터 대비 YJIT 3.4.0 사용 시 요청 지연 시간이 단축되었으며, 작년 대비 성능은 소폭 개선되고 메모리 사용량은 큰 변화가 없었습니다. p50 및 p99 지연 시간 또한 개선되었습니다.
Ruby 3.4 릴리스와 함께 제공되는 YJIT 3.4는 성능, 메모리 효율성, 그리고 개발자 경험 측면에서 여러 개선을 이루었습니다. 특히 `--yjit-mem-size` 옵션과 같은 편의성 향상은 사용자들에게 직접적인 이점을 제공합니다. 다양한 내부 최적화와 개선된 벤치마크 및 프로덕션 성능 데이터는 YJIT가 Ruby 애플리케이션 성능 향상을 위한 강력한 도구임을 다시 한번 입증합니다. YJIT 팀은 앞으로도 Ruby 성능 개선을 위한 다양한 연구와 노력을 계속할 계획입니다. Ruby 3.4는 공식 릴리스 페이지에서 다운로드 가능하며, YJIT 사용을 통해 더욱 빠르고 효율적인 Ruby 개발 및 운영 환경을 경험하시길 바랍니다.