JavaScript - Lazy evaluation

Code_Alpacat·2022년 6월 9일
2

JavaScript - 중급

목록 보기
6/11

*지연 평가 (Lazy Evaluation)

  • 제때 계산법
  • 느긋한 계산법
  • 제너레이터/이터레이터 프로토콜을 기반으로 구현

1) 지연 평가와 즉시 평가의 차이

  • array(infinity)라는 무한한 크기의 배열이 있다면 앞의 10개의 배열을 slice를 해야할 때 어떤 일이 발생할까?
  • 분명 array를 생성하는데 시간이 무한하게 걸리므로 브라우저가 터져버릴 것이다.
L.range = function* (l) {
      let i = -1;

      while (++i < l) {
        //제네레이터로 생성
        yield i;
      }
      return res;
    };

console.time('');
console.log(take(5, range(Infinity)));
console.timeEnd('');
//아래는 똑같이 5만큼만 시간이 들지만 위는 브라우저가 감당하지 못함
console.time('');
console.log(take(5, L.range(Infinity)));
console.timeEnd('');
  • 이는 제네레이터를 통해 배열을 필요할 때 평가하느냐 vs 미리 이터러블을 미리 생성해놓고 조건에 맞게 평가하느냐의 차이다.

2) map, filter의 지연 평가

  • L.map
    L.map = function *(f, iter) {
      for (const a of iter) yield f(a);
    };
    var it = L.map(a => a + 10, [1, 2, 3]);
  • L.filter
L.filter = function *(f, iter) {
      for (const a of iter) if (f(a)) yield a;
    };
   var it = L.filter(a => a % 2, [1, 2, 3, 4]);
  • 이쯤, 드는 의문은 기존의 내장 함수인 map과 filter를 활용하지 않고 매번 이 지연 평가를 위한 함수를 선언해줘야만 하는가? 였다.

3) lodash 활용

  • 즉시 평가의 예시

    아래의 예시는 100000개의 배열을 선언하고, 그 이후에 순차적으로 map filter 등을 실행하므로 효율이 매우 낮음

Array(100000).fill().map((v, i) => i)
  .map((v) => v + 1)
  .filter((v) => v % 3 === 0)
  .slice(0, 10);
  • 지연 평가의 예시

    lodash의 range를 이용해 구현하면, 자동으로 lodash가 지연 평가를 해주므로, 매번 실행 시에 map과 filter slice를 실행하고 지연 평가를 위해value()를 실행한다.

    • 굳이 100001개의 이터러블을 미리 만들지 않으므로 10의 크기가 되면 멈추고, 효율은 무려 2000배의 차이가 난다.
_().range(100001)
  .map((v) => v + 1)
  .filter((v) => v % 3 === 0)
  .slice(0, 10)
  .value();

출처: (https://www.zerocho.com/category/JavaScript/post/5c0cb264f82a70001e47db0c)

profile
In the future, I'm never gonna regret, cuz I've been trying my best for every single moment.

0개의 댓글