Ruby 문자열의 특징 및 최적화
Ruby 문자열은 대부분의 언어와 달리 기본적으로 가변(mutable)하며, 100가지 이상의 인코딩을 지원합니다. 불변 문자열은 메모리 효율성(string view, interning)과 안전성(멀티스레딩, 해시 키)에서 이점이 있으며, Ruby는 Object
freeze와 내부 최적화(해시 키 동결, 불변 string view)를 통해 이를 부분적으로 활용합니다.
frozen_string_literal의 도입과 VM 개선
Ruby 2.1.0은 String
freeze에 대한 opt_str_freeze VM 명령어를 도입해 불필요한 문자열 복사를 줄였습니다. Ruby 2.3에서는 # frozen_string_literal: true 주석이 추가되어 컴파일러가 putobject 명령어를 사용, 문자열을 직접 스택에 올려 추가 복사를 제거함으로써 GitHub에서 3%의 메모리 할당 감소 효과를 가져왔습니다.
Ruby 3.0 계획 철회와 ‘Chilled Strings’
2015년 Matz는 Ruby 3.0에서 문자열 리터럴을 기본 불변으로 만들 계획을 발표했으나, 2019년 호환성 문제로 철회했습니다. 저자는 이 결정이 과도했으며, 실제 마이그레이션이 키워드 인자 변경보다 쉬웠다고 주장합니다. 이에 저자는 frozen_string_literal 주석 없이도 성능 이점을 유지하기 위해 ‘chilled strings’ 개념을 제안했고, Ruby 3.4부터 주석 없는 파일의 문자열 리터럴이 putchilledstring으로 생성되어 첫 변경 시 경고를 발생시킵니다. 이는 미래의 기본값 전환을 위한 단계입니다.
성능 영향
벤치마크 결과, frozen_string_literal 사용 시 Lobsters(Rails) 8-9%, railsbench 4-6%, liquid-render 11%의 속도 향상이 관찰되었으며, 이는 불필요한 문자열 복사 감소로 Ruby VM의 작업량이 줄어들기 때문입니다.