Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

제너레이터 사용하기 - 지연 평가 (lazy evaluation) 본문

💬 언어/Javascript

제너레이터 사용하기 - 지연 평가 (lazy evaluation)

Chamming2 2021. 5. 3. 21:46
function* f1() {
  yield 10;
  yield 20;
  return "완료";
}

const gen = f1();

제너레이터 문법을 알고 계신 분들이라도, 제너레이터를 어떻게 사용할 수 있는지에 대해서는 잘 모르는 분들도 계실 것입니다. (저도 잘 몰랐습니다..!)

 

오늘은 제너레이터를 통해 성능을 개선할 수 있는 지연 평가(lazy evaluation) 라는 기법을 간단히 구현해 보도록 하겠습니다.

📋 지연 평가

지연 평가는 자바스크립트에만 존재하는 개념은 아니고, 함수형 프로그래밍에서 등장한 개념입니다.

코드와 함께 지연 평가의 개념을 간단히 소개해보겠습니다.

const a = 3 + 5;
const b = 2 + 4;

console.log(a); // 8

변수 a에는 3 + 5의 계산 결과인 8이 할당되어 코드 최하단부에서 이를 출력(사용)하고 있고, 변수 b에는 2 + 4의 결과인 6이 할당되지만 사용하지 않고 있습니다.

 

그렇다면 사용하지도 않을 b에 들어갈 값을 계산할 필요가 있을까요? 글쎄요...🤔

 

이렇게 불필요한 코드 실행(연산)을 막기 위해 계산을 늦추는 것이 지연 평가로, 한번 실제 시나리오를 바탕으로 예를 들어 보겠습니다.

지연 평가와 제너레이터

1부터 N까지의 숫자 중, 10의 배수를 작은 순서대로 5개 찾아 리턴하는 코드를 작성한다고 가정하겠습니다.

function makeArray(N) {
  const arr = [];
  let idx = 1;
  while (idx <= N) {
    arr.push(idx++);
  }
  return arr;
}

function dividableWith10(iter) {
  const arr = [];
  for (const elem of iter) {
    if (elem % 10 === 0) {
      arr.push(elem);
    } else if (arr.length === 5) {
      return arr;
    }
  }
}

const arr = makeArray(50)
console.log(dividableWith10(arr)); // [ 10, 20, 30, 40, 50 ]

아마 대부분의 사람들이 이와 비슷한 형태로 코드를 작성할 것이라 생각되는데요, 제너레이터를 사용하면 이 코드를 훨씬 효율적으로 개선할 수 있습니다.

// 제너레이터 사용
function* makeIterable(N) {
  let idx = 1;
  while (idx <= N) {
    yield idx++;
  }
}

// dividableWith10 함수는 그대로입니다.
function dividableWith10(iter) {
  const arr = [];
  for (const elem of iter) {
    if (elem % 10 === 0) {
      arr.push(elem);
    } else if (arr.length === 5) {
      return arr;
    }
  }
}

const iter = makeIterable(50);
console.log(dividableWith10(iter)); // [ 10, 20, 30, 40, 50 ]

얼핏 봐서는 차이를 눈치채지 못할 수도 있지만 dividableWith10 함수에 전해지는 인자가 변했는데요, 이전에는 1부터 N이 담긴 배열을 전달하고 있었다면 새로운 코드에서는 제너레이터 객체를 인자로 전달하고 있습니다.

📈 같은 동작, 다른 성능

N이 커질수록 두 코드의 실행속도에는 차이가 생기게 되는데요, 배열을 사용할 때는 1부터 N까지가 담긴 전체 배열을 전달하고 그 안의 값을 사용했지만 제너레이터 객체를 사용할 때는 for-of 문을 순회하면서 필요한 범위 내의 값만을 호출해 사용하기 때문에 I/O 성능을 크게 개선할 수 있습니다.

 

제너레이터를 적절히 활용하면 성능 외에도 얻을 수 있는 장점이 꽤 있으며, 오늘 다룬 지연 평가는 자바스크립트뿐만 아니라 파이썬 및 자바 등의 언어에서도 적용할 수 있는 기법이니 한번 시간을 내어 익혀 보시길 바라겠습니다. 😆

 

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆