[Ruby] Lazy Enumerator 사용하기

1. lazy enumerator란?

Lazy Enumerator는 루비 2.0 에서 처음 등장한 기능으로, method chain을 사용할 때 chain을 효율적으로 수행할 수 있도록 도와준다. 이 기능을 알고 난 후에 코드의 양은 줄어들었고 가독성은 오히려 늘어나게 되었다. 매우 좋다.

.

2. 사용법

사용법은 어렵지 않다. 기존 enumerator를 사용하는 것처럼 take(n).to_a를 하면 앞에서부터 10개의 아이템을 array로 만들어준다

arr = [1, 3, 5, 2, 4, 6]
arr.lazy.select { |i| i <= 3 }.take(2).to_a # => [1, 2]
arr.lazy.select { |i| i <= 3 }.first(2) # => [1, 2]

..

3. 비교

lazy를 사용하지 않을 때와 비교

1부터 무한대까지의 숫자 중, 3의 배수를 2개

max = 1_000_000_000_000
(1..max).select { |x| x % 3 == 0 }.first(2) # => 오래걸림 => [3, 6]
(1..max).lazy.select { |x| x % 3 == 0 }.first(2) # => [3, 6]

위에서 보듯이 lazy를 사용하지 않으면, 1 ~ 1,000,000,000,000 에 대해서 select를 모두 실행 후 first(2)를 실행하기 때문에 시간이 오래 걸린다.

물론 lazy를 사용하지 않고 코드의 양을 늘리면 이 문제를 해결할 수 있다.

arr = []
(1..max).each do |x|
  arr << x if x % 3 == 0
  break if arr.size == 2
end

.

4. 참고

lazy enumerator의 ruby 구현은 여기 서 볼 수 있다. C 구현은 생략