Backend/Ruby

[번역] What’s new in Ruby 3.3(Ruby 3.3의 새로운 기능)

Seyun(Marco) 2023. 12. 24. 20:42
728x90

[번역] What’s new in Ruby 3.3(Ruby 3.3의 새로운 기능)

 

What's new in Ruby 3.3

Every year on Christmas day, the Ruby core team releases a new version of Ruby. This year will likely be no different, and we can expect Ruby 3.3 next week. This year, the primary focus of the release is performance and developer experience. There aren’t

nithinbekal.com

매년 크리스마스에 Ruby의 새 버전을 Ruby Core 팀이 출시합니다. 올해도 다르지 않을 것 같으며, 다음 주에 Ruby 3.3이 출시될 것으로 예상됩니다.

올해 출시의 주요 핵심은 개발자 경험과 성능입니다. 이전 버전처럼 언어 기능에 큰 변화가 있는 것은 아니기 때문에 이번 포스팅은 평소보다 짧아질 예정입니다. 이번 출시의 주요 내용은 아래와 같습니다.

YJIT

Ruby의 JIT 컴파일러인 YJIT는 지난 몇 년 동안 놀라운 발전을 이루었습니다. 올해도 계속해서 속도는 빨라지고, 메모리 사용량은 줄었습니다.

BasecampShopify와 같은 회사들에서는 이미 3.3의 Preview 버전을 프로덕션에 적용하였으며, YJIT가 없는 3.3.0에 비해 평균 응답 시간이 약 15% 향상되었습니다. 실제로, YJIT는 Rails 앱의 속도를 높이는 데 매우 효과적이어서 Ruby 3.3을 사용하는 경우 새로 생성된 Rails 앱에서 기본적으로 활성화됩니다.

YJIT를 런타임 시 활성화 할 수 있는 새로운 메서드인 RubyVM::YJIT.enable가 도입되었습니다. 이 메서드는 앱을 빠르게 로드하고, 부팅한 후에 YJIT를 활성화하려는 경우 유용할 수 있습니다. 이것이 Rails 앱을 초기화 시 JIT를 활성화하는 데 사용하는 것입니다.

RJIT

실험적인 JIT 컴파일러인 RJIT가 도입되었습니다. 이것은 순수한 Ruby로 작성되었으며, Ruby 3.2에서 사용 가능한 MJIT의 대안입니다. RJIT는 YJIT보다 훨씬 더 많은 메모리를 사용하여 실험용으로만 존재합니다. 프로덕션에서는 항상 YJIT를 사용해야 합니다.

IRB

수년 동안 선호하는 디버깅 도구로 pry와 byebug를 사용하다가 지난 몇 달 동안 모든 나의 디버깅에 IRB를 사용하도록 전환하였습니다. 이번 출시에서 IRB와 내장된 debug gem의 통합이 크게 개선되어서 더 이상 pry와 byebug가 필요하지 않게 되었습니다.

Range

Range 클래스에 몇 가지 변화가 있습니다. overlap? 메서드가 추가되었습니다:

(1..3).overlap?(3..5) # true
(1..3).overlap?(4..6) # false

추가 정보) overlap? 메서드는 두 개의 범위를 비교하여 겹치는지 확인하는 메서드입니다. 현재까지 Rails에 내장된 메서드입니다.

또한, reverse_each 메서드는 시작이 없는 범위에서도 사용할 수 있습니다.

(..10).reverse_each.take(3) #=> [10, 9, 8]

추가 정보) reverse_each는 역순으로 탐색하는 메서드입니다.

Prism parser

Prism이라는 새로운 parser가 default gem으로 도입되었습니다. 에러에 더 강하며, ripper 대신 사용할 수 있습니다. 이는 Ruby 구현 전반에 걸쳐 사용 가능하며, 현재 MRI, JRuby, TruffleRuby, Sorbet에 통합되고 있습니다.

Prism을 사용하면, Prism.parse 메서드를 사용해 코드를 분석할 수 있고 아래와 같은 결과를 얻을 수 있습니다.

> Prism.parse("1 + 2")

#<Prism::ParseResult:0x000000010f5518c8
 @comments=[],
 @data_loc=nil,
 @errors=[],
 @magic_comments=[],
 @source=#<Prism::Source:0x000000012aa77530 @offsets=[0], @source="1 + 2", @start_line=1>,
 @value=
  @ ProgramNode (location: (1,0)-(1,5))
  ├── locals: []
  └── statements:
      @ StatementsNode (location: (1,0)-(1,5))
      └── body: (length: 1)
          └── @ CallNode (location: (1,0)-(1,5))
              ├── flags: ∅
              ├── receiver:
              │   @ IntegerNode (location: (1,0)-(1,1))
              │   └── flags: decimal
              ├── call_operator_loc: ∅
              ├── name: :+
              ├── message_loc: (1,2)-(1,3) = "+"
              ├── opening_loc: ∅
              ├── arguments:
              │   @ ArgumentsNode (location: (1,4)-(1,5))
              │   ├── flags: ∅
              │   └── arguments: (length: 1)
              │       └── @ IntegerNode (location: (1,4)-(1,5))
              │           └── flags: decimal
              ├── closing_loc: ∅
              └── block: ∅,
 @warnings=[]>

M:N thread scheduler

thread와 ractor의 성능을 향상시키기 위해 새로운 M:N thread scheduler 스케줄러가 도입되었습니다. 여기서 M은 ractor의 수이고, N은 기본 스레드 수입니다. (예: CPU 코어 수와 동일) 이를 통해 우리는 기본 스레드를 생성하는 오버헤드를 지불하지 않고, 각각 많은 ractor를 생성할 수 있습니다.

추가정보) ractor란? Ruby 3.0에서 도입된 병렬 처리를 위한 새로운 추상화입니다. Ractor는 Ruby의 "Actor-model"에서 파생된 이름으로, 병렬 실행을 가능하게 하는 독립적인 병렬 작업 단위를 의미합니다. Ractor는 각각 자체의 스레드를 가지며, 이 스레드는 다른 Ractor와 공유되지 않습니다. 이는 Ruby의 전역 VM 락(GVL) 문제를 해결하는 데 도움이 됩니다. GVL은 한 번에 하나의 스레드만 Ruby 코드를 실행할 수 있도록 제한하는데, 이로 인해 멀티 코어 CPU를 최대로 활용하는 것이 어렵습니다. Ractor를 사용하면, 각 Ractor가 자체 스레드를 가지므로 여러 Ractor가 동시에 실행될 수 있습니다. Ractor는 메시지 전달을 통해 통신합니다. 이는 Ractor 간에 상태를 공유하지 않고, 오직 메시지를 통해서만 데이터를 교환하도록 강제합니다. 이러한 특성은 병렬 프로그래밍에서 발생할 수 있는 데이터 경쟁 조건을 방지하는 데 도움이 됩니다. Ractor는 Ruby에서 병렬 처리를 위한 강력한 도구로, CPU 집약적인 작업을 병렬로 처리하거나, IO 집약적인 작업을 동시에 처리하는 데 유용합니다.

다른 변화

  • Ruby 3.4에서 블록의 첫 번째 인자에 대한 참조로 사용되는 제안이 있습니다. it 인자 없이 호출되는 것은 deprecated가 될 예정이며, 경고가 표시됩니다.
  • Bison은 유지 관리성을 향상시키기 위해 Lrama parser 생성기로 대체되었습니다.
  • 더욱 성능을 향상시키기 위해 GC가 많이 최적화되었습니다.

더 읽어보기

이 포스트를 통해 가장 흥미롭다고 생각하는 변경 사항 중 일부를 강조하려고 노력하고 종종 사용하지 않을 수 있는 기능은 건너뜁니다. 출시에 대해 보다 포괄적으로 살펴보려면 공지변경 로그를 살펴보는 것이 좋습니다.

728x90
728x90