Ruby 프로젝트에서 최고의 성능을 끌어내고 싶다면 파이버(Fiber)를 제대로 이해하고 활용하는 것이 필수입니다. 이 글에서는 파이버가 무엇인지, 어떻게 작동하는지, 그리고 실전에서 어떻게 활용할 수 있는지 차근차근 살펴보겠습니다.
파이버란 무엇일까요?
파이버는 코드를 실행하고 자신의 진행 상황을 스스로 추적하는 일종의 '작업 단위'입니다. 다시 말해, 파이버는 동시성(concurrency) 메커니즘입니다.
네, 맞습니다! 스레드와 비슷한 역할을 합니다. 하지만 결정적인 차이가 하나 있습니다. 바로 스레드보다 훨씬 세밀하게 제어할 수 있다는 점입니다.
어떤 점에서 더 많은 제어권을 가질까?
스레드의 경우 운영체제(OS)가 언제 실행하고 언제 멈출지를 결정합니다. 하지만 파이버는 다릅니다!
개발자가 직접 파이버에게 언제 실행할지, 언제 멈출지 정확히 지시해야 합니다.
파이버 vs 스레드
스레드는 마치 백그라운드에서 저절로 돌아가는 듯한 느낌을 줍니다. 반면 파이버는 그렇지 않습니다.
파이버가 실행되는 동안에는 그 파이버가 곧 메인 프로그램이 됩니다. 개발자가 멈추라고 지시하기 전까지는 계속 실행됩니다.
코드 예제로 확인해 보겠습니다!
파이버 사용 예제
Fiber.new에 블록을 전달하면 새로운 파이버를 만들 수 있습니다.
예제:
f = Fiber.new { puts 1 }
그런 다음 resume 메서드로 파이버를 실행합니다.
이렇게요:
f.resume
이 코드는 1을 출력한 뒤, 제어권을 메인 프로그램으로 되돌려줍니다.
그렇다면 파이버는 어떻게 멈출까요?
Fiber.yield 메서드를 사용합니다. 주의할 점은 블록에서 사용하는 yield 키워드와는 전혀 다른 별개의 메서드라는 것입니다.
예제:
f = Fiber.new { puts 1; Fiber.yield; puts 2 }
f.resume
# 1
f.resume
# 2
resume으로 파이버를 시작하면 1을 출력한 후 멈춥니다. 그리고 다시 resume을 호출하면...
멈췄던 지점 그대로부터 이어서 실행되어 2를 출력합니다.
참고: 이미 종료된 파이버를 다시 resume하면
FiberError: dead fiber called오류가 발생합니다. 더 이상 실행할 코드가 없기 때문입니다.
바로 이 점이 파이버가 유용한 이유입니다!
파이버 내부에서 Fiber.yield를 호출하는 것은 마치 '일시정지 버튼'을 누르는 것과 같습니다. 덕분에 반복문 중간이나 파이버 블록 안의 어떤 코드든 원하는 시점에 멈추고 재개할 수 있습니다.
파이버와 반복문: 무한 수열 만들기
이 '일시정지 버튼' 효과를 활용하면 무한 수열도 손쉽게 만들 수 있습니다.
필요한 요소:
- 파이버
- 반복문(loop)
- 카운터
예를 들어 팩토리얼 수열:
factorial =
Fiber.new do
count = 1
loop do
Fiber.yield (1..count).inject(:*)
count += 1
end
end
이 파이버는 resume 메서드를 호출할 때마다 수열의 다음 숫자를 반환합니다. 원하는 만큼 몇 번이고 호출할 수 있습니다.
예제:
Array.new(5) { factorial.resume }
# [1, 2, 6, 24, 120]
훌륭하죠!
파이버와 IO: 비동기 작업 처리
네트워크 연결처럼 대기 시간이 필요한 작업에서는 파이버가 스레드보다 더 빠르고 효율적입니다.
왜 그럴까요?
파이버는 컨텍스트 스위치(context switch) 횟수가 적기 때문입니다.
컨텍스트 스위치란 CPU가 현재 작업에서 다른 작업으로 전환하는 것을 의미합니다.
비용 자체는 작지만, 누적되면 상당한 부담이 됩니다!
실제로 Linux의 perf 도구로 테스트해본 결과, 간단한 Ruby 애플리케이션에서 파이버가 생성하는 컨텍스트 스위치는 스레드보다 3배나 적었습니다.
괜찮아 보이나요?
지금 바로 파이버를 사용해볼 수 있는 방법:
IO.select메서드 + 리액터(Reactor) 디자인 패턴- async 젬(gem)
- falcon 애플리케이션 서버
물론 만능 해결책은 없지만, 직접 테스트해보면서 파이버가 프로젝트에 어떤 도움을 줄 수 있는지 확인해볼 가치는 충분합니다 🙂
마무리 정리
지금까지 Ruby의 파이버에 대해 배웠습니다! 파이버를 사용하면 원하는 시점에 멈추고 재개할 수 있는 코드 단위를 만들 수 있습니다.
이제 직접 한번 사용해볼 차례입니다.
읽어주셔서 감사합니다!