일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- k8s
- JavaScript
- react
- 알고리즘
- 백준
- node.js
- 컴퓨터공학
- CSS
- 리액트
- 이슈
- 클라우드
- kubernetes
- 솔리디티
- 프론트엔드
- HTML
- 이더리움
- 블록체인
- 쿠버네티스
- AWS
- 백엔드
- 자바스크립트
- 가상화
- 파이썬
- es6
- BFS
- docker
- next.js
- 타입스크립트
- 웹
- TypeScript
- Today
- Total
즐겁게, 코드
제너레이터 사용하기 - 지연 평가 (lazy evaluation) 본문
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 성능을 크게 개선할 수 있습니다.
제너레이터를 적절히 활용하면 성능 외에도 얻을 수 있는 장점이 꽤 있으며, 오늘 다룬 지연 평가는 자바스크립트뿐만 아니라 파이썬 및 자바 등의 언어에서도 적용할 수 있는 기법이니 한번 시간을 내어 익혀 보시길 바라겠습니다. 😆
'💬 언어 > Javascript' 카테고리의 다른 글
데이터 페칭 로직 우아하게 개선하기 (3) | 2021.06.14 |
---|---|
너! 배열이 되어라! - Array.from() 메서드 사용하기 (1) | 2021.05.29 |
nullish coalescing 연산자로 널 참조 방지하기 (0) | 2021.05.02 |
변수의 호이스팅, 그리고 TDZ의 함정 (0) | 2021.04.11 |
제너레이터부터 리덕스 사가까지 - 01. 제너레이터 (0) | 2021.04.05 |