Ruby의 속도를 높이기 위한 C 코드의 Ruby 재작성
(jpcamara.com)Ruby의 성능 향상: C를 Ruby로 다시 작성하기
Ruby의 성능 비교
- 최근 언어 비교 리포지토리에서 Ruby는 R과 Python보다 빠르지만, 세 번째로 느린 언어로 평가됨.
- 벤치마크는 "Loops"와 "Fibonacci" 두 가지로 구성되며, 각각 루프와 조건문, 함수 호출 오버헤드 및 재귀 성능을 강조함.
Ruby와 Node.js의 성능 비교
- M3 MacBook Pro에서 Ruby 3.3.6은 루프 예제에서 28초, 피보나치 예제에서 12초 소요됨.
- Node.js는 두 예제 모두 1초 정도 소요됨.
- M2 MacBook Air에서는 Ruby의 성능이 더 나빠짐.
벤치마크의 의미
- 이러한 벤치마크는 실제로 큰 의미가 없을 수 있음.
- Python은 가장 느린 언어로 평가되었지만, GitHub에서 가장 많이 사용되는 언어임.
- 프로그래밍 언어는 효율적이어야 하며, 언어의 유용성과 생산성이 성능보다 중요함.
YJIT의 적용
- YJIT를 적용하면 피보나치 성능이 크게 향상됨.
- 루프 예제에서는 성능 향상이 미미함.
Ruby 코드 최적화
-
Range#each
는 C로 작성되어 YJIT 최적화가 불가능함. -
Integer#times
는 Ruby 3.3에서 C에서 Ruby로 변환되어 YJIT 최적화가 가능함. -
Array#each
는 Ruby 3.4에서 C에서 Ruby로 변환됨.
Integer#times
최적화
-
Integer#succ
는i += 1
보다 빠르게 동작함. - YJIT는
Integer#times
를 최적화하여 성능을 크게 향상시킴.
Array#each
최적화
-
Array#each
는 Ruby 3.4에서 C에서 Ruby로 변환되어 YJIT 최적화가 가능함. -
Primitive
모듈을 사용하여 C 코드를 Ruby에서 평가함.
Ruby Microbench 리포지토리
- 다양한 Ruby 버전과 YJIT를 사용하여 벤치마크를 실행함.
- Ruby 3.4 YJIT는 성능이 크게 향상됨.
range#each
최적화
-
Range
클래스를 순수 Ruby로 구현하여 성능을 향상시킬 수 있음.
YJIT 표준 라이브러리
- YJIT 팀은 C 코드를 Ruby로 대체하여 성능을 향상시키고 있음.
-
with_yjit
블록을 사용하여 YJIT가 활성화되었을 때 Ruby 구현을 사용함.
YJIT 최적화 조사
- YJIT는 Ruby VM 바이트코드를 기계어로 변환하여 성능을 최적화함.
-
Integer#succ
의 기계어 코드를 분석하여 YJIT의 최적화 과정을 이해함.
Hacker News 의견
-
루프 예제는 10억 번 반복하며 중첩 루프를 사용함. 이 벤치마크는 첫 두 줄에서 99% 이상의 시간을 소비할 것이라고 추측됨
- 배열 요소에 대한 활력 분석을 통해 전체 외부 루프를 제거할 수 있으며, 프로그램을 간단하게 변환할 수 있음
- 컴파일러가 이러한 분석을 수행할 수 있는지 궁금함
-
u
가 컴파일 시점에 알려지지 않더라도 내부 루프는 몇 가지 명령어로 대체 가능함
-
Ruby의 향후 버전에 대한 언급이 있으며, Ruby 3.4.0은 이번 크리스마스에, Ruby 3.5.0은 다음 크리스마스에 출시될 예정임
- Python의 최소 JIT가 이러한 루프에 어떤 영향을 미칠지 궁금함
- Python 3.13은 JIT가 활성화된 상태로 빌드되어야 하며, 이를 통해 벤치마크를 실행해보는 것이 흥미로울 것임
-
Ruby에 대한 애정이 여전히 남아있음. Matz에게 감사함
-
Integer#succ
의 성능 개선 PR이 2024년 초에 있었으며, 이를 통해Integer#succ
를 사용하는 이유를 이해하게 됨-
Integer#succ
는 루프 메서드를 재작성할 때 사용되며, 해석기에서opt_succ (i = i.succ)
가putobject 1; opt_plus (i += 1)
보다 더 빠르게 처리됨 - 개인적으로
#succ
를 가독성 때문에 자주 사용하며, UUID 라이브러리의#bytes
메서드에서 두 번 사용하여 코드 읽기 시 "비트 슬라이싱 모드"를 유지함
-
-
TruffleRuby와 관련된 경험을 공유하며, TruffleRuby가 Node.js보다 빠르고 Bun이나 Golang에 근접함
- 제공된 벤치마크가 변경 후의 TruffleRuby 속도를 보여주는지 확신할 수 없음
- 벤치마크를 검증하고 메인 저장소에 커밋으로 추가하고 싶음
-
Ruby가 매우 빨라졌으며, TruffleRuby는 더욱 인상적임
-
YJIT가 Rust로 작성되었다는 사실을 몰랐음
-
Python이 벤치마크에서 가장 느린 언어였지만, 2024년 10월 기준으로 Github에서 가장 많이 사용되는 언어임
- 언어의 느림과 인기가 상관관계가 있는 것 같음
-
더 많은 언어를 포함한 오래된 언어 비교 저장소가 있음
-
Advent of Code 솔루션에 큰 변화를 가져왔으며, 놀랍도록 유사하게 보임