[JavaScript] L.range, L.map, L.filter, take의 평가 순서 및 효율성

2023. 5. 3. 22:52· Node.js/JS
목차
  1. 엄격한 계산과 느긋한 계산의 효율성 비교
const L = {};

L.range = function *(l) {
	let i = -1;
    while (++i < l) yield i;
};

L.map = curry(function *(f, iter) {
    iter = iter[Symbol.iterator]();
    let cur;
    while (!(cur = iter.next()).done) {
	    const a = cur.value;
	    yield f(a);
    }
});

L.filter = curry(function *(f, iter) {
    iter = iter[Symbol.iterator]();
    let cur;
    while (!(cur = iter.next()).done) {
	    const a = cur.value;
	    if (f(a)) yield a;
    }
};

const take = curry((l, iter) => {
	const res = [];
    iter = iter[Symbol.iterator]();
    let cur;
    while (!(cur = iter.next()).done) {
	    const a = cur.value;
	    res.push(a);
        if (res.length === l) return res;
    }
    return res;
});

이전에 나온 함수들 중에 지연 평가를 하는 함수들은 위와 같다.

 

여기서 아래와 같이 위 함수들을 나열하여 다음과 같이 사용할 수 있다.

go(L.range(10),
	L.map(n => n + 10),
   	L.filter(n => n % 2),
    take(2),
    console.log);

그런데 이렇게 실행하는 경우 가장 먼저 take 함수를 실행하게 된다. 실제로 debug모드에서 멈추게 되면 take를 먼저 순회한다. 하지만 더 자세히 진행순서를 확인해보면, take 함수의 let cur; 까지 진행을 하다가 while (!(cur = iter.next()).done) { 라인을 만났을 때, filter 함수로 넘어간다.

 

L.range를 한 결과가 코드의 평가를 미뤄둔 이터레이터가 L.map으로 들어가며, 동일하게 L.map에서도 평가를 미뤄둔 L.filter로 넘어간다. 이후 최종적으로 take 함수의 인자로 들어가게 되는 것이다.

 

그래서 값을 평가하기 시작하면 take -> L.filter -> L.map -> L.range 순으로 실행된다. 이제 다시 L.range에서 값을 yield하고, L.map -> L.filter -> take 로 넘어간다.

 

즉, 각 함수마다 모두 값을 평가하여 넘어가는 것이 아니라, 0부터 10까지 각 원소가 모든 함수를 지난 다음 그 다음 원소로 넘어가게 되는 것이다 .

 


엄격한 계산과 느긋한 계산의 효율성 비교

엄격한 계산은 모든 배열을 계산한 다음 각각 절차를 진행한다.

 

느긋한 계산은 다 확인하지 않지 않고 실제 사용될 때만 절차를 진행한다.

 

그래서 예를 들어 take 함수의 인자값이 2인데, range 함수의 인자값이 100,000이라면 range에서 모든 값을 평가한다 한들 take에서 2개의 값만 뽑아낸다. 하지만, L.range와 take를 사용하면 2 번의 순회만 하고 원하는 값을 추출해낼 수 있다.

 

심지어 무한수열의 경우도 사용이 가능하다.

 


제너레이터를 활용하는 함수가 어떻게 동작하게 되는지 충분히 알 수 있었다. 평가를 뒤로 미루기 때문에 각각의 함수가 본인이 평가되는 시점에서만 값을 평가하게 되고 각 함수간의 절차가 유동적으로 변한다. 따라서 한 함수가 끝나고 나서야 다음 함수가 실행되는 비유동적인 절차를 밟지 않고 차례대로 함수를 순회한다는 점에서 좋은 방법인 것 같다. 특히 range와 take가 그러했다. range에서 모든 값을 평가하여 다음으로 넘겼을 때, 이 값들이 모두 사용되리라는 보장 없이 그저 함수를 실행시키면 효율적이지 않기 때문이다. 이는 비단 프론트엔드에만 적용할 수 있는 것이 아니라, 백엔드 소스코드에도 충분히 접목시킬 수 있을 것으로 보인다.

 

출처: 인프런 함수형 프로그래밍과 JavaScript ES6+

저작자표시 비영리 (새창열림)

'Node.js > JS' 카테고리의 다른 글

[JavaScript] map, filter & reduce로 결과를 만드는 함수 생성  (0) 2023.05.07
[JavaScript] map, filter 계열 함수들이 가지는 결합 법칙, 지연평가의 장점  (0) 2023.05.05
[JavaScript] reduce, map, filter, take 중첩 사용  (0) 2023.05.03
[JavaScript] 제너레이터/이터레이터 프로토콜로 구현하는 지연 평가  (0) 2023.05.02
[JavaScript] take 함수  (2) 2023.05.02
  1. 엄격한 계산과 느긋한 계산의 효율성 비교
'Node.js/JS' 카테고리의 다른 글
  • [JavaScript] map, filter & reduce로 결과를 만드는 함수 생성
  • [JavaScript] map, filter 계열 함수들이 가지는 결합 법칙, 지연평가의 장점
  • [JavaScript] reduce, map, filter, take 중첩 사용
  • [JavaScript] 제너레이터/이터레이터 프로토콜로 구현하는 지연 평가
턴태
턴태
import { Dream } from "future";
턴태
턴태의 밑바닥부터 시작하는 de-vlog
턴태
전체
오늘
어제
  • ROOT (187)
    • Node.js (37)
      • ES6 (1)
      • TypeScript (3)
      • Express.js (16)
      • NestJS (16)
      • JS (24)
    • 프론트엔드 (29)
      • CS (5)
    • 백엔드 (1)
      • 검색 (2)
      • Database (1)
    • 기타 툴 (1)
      • git (1)
    • 데브옵스 & 인프라 (19)
      • Kubernetes (15)
      • Docker (2)
      • Monitoring (1)
      • IaC (1)
    • Algorithm (90)
      • Implementation & simulation (5)
      • Math (4)
      • Brute Force (1)
      • String (0)
      • Graph (5)
      • Recursion & Backtracking (19)
      • Divide & Conquer (2)
      • Dynamic Programming (18)
      • Greedy (13)
      • Priority Queue (2)
      • Binary Search (6)
      • Data Structure (7)
      • Shortest Path (5)
      • Minimum Spanning Tree (1)
      • Sorting (1)
      • Prefix Sum (1)
    • Linux (1)
      • Ubuntu (1)
    • Diary (5)
      • Algorithm (1)
      • Conference (1)
      • Retrospective (3)
    • Book (0)
      • Self-Development (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 타입스크립트
  • N과 M
  • 함수형 프로그래밍
  • 쿠버네티스
  • 파이썬
  • Express
  • 자바스크립트
  • Kubernetes
  • 디프만
  • 토이프로젝트
  • python
  • backtracking
  • k8s
  • Omuk
  • 익스프레스
  • dynamic programming
  • 네스트
  • nestjs
  • 다이나믹 프로그래밍
  • baekjoon
  • 오먹
  • 노드
  • node.js
  • GREEDY
  • 인프런X디프만
  • TypeScript
  • Toy Project
  • 백트래킹
  • 백준
  • 인프런

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
턴태
[JavaScript] L.range, L.map, L.filter, take의 평가 순서 및 효율성
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.