지연성, take

nn·2023년 6월 23일
0

range, L.range

const range = (l) => {
	let res = [];
	let i = -1 ;
		while ( ++i < l){
			res.push(i);
		}
	return res;
}

log(range(4)) // [0,1,2,3]

위 함수는 l인자를 입력받아 0부터 l만큼 하나씩 숫자를 늘려가며 배열의 요소를 추가하는 함수이다.

L.range

L.range는 제너레이터로 만들어 이터레이터를 반환하는 함수이다.

const L ={}
L.range = function*(l) {
	let i = -1 ;
		while ( ++i < l){
			yield i
		}
}
const lrange = L.range(4)
for (const a of lrange) {
	log(a);
}

L.range(4)를 반복문 for of를 통해서 출력하면 위와 같이 요소 하나씩 출력된다.

그럼 range와 L.range의 다른 점은 뭘까 ?

L.range는 제너레이터로 만들어 이터레이터를 반환하는 함수이기 때문에
L.range(4) 자체를 콘솔에 찍어보면
range(4)처럼 [0,1,2,3]이 나오지 않는다.

이터레이터는 for of 반복문에서 next() 함수를 통해 평가되기 때문에 next()가 호출되기 전에는 값이 존재하지 않는다.

즉, 값이 사용되려는 시점에 만들어지게 된다.

차이를 정확하게 하기위해 range와 L.range에 연산을 추가해보자.


add

const add = (a,b) => a + b;

const range_add = (list) => reduce(add, list);

log(range_add(range(4))); // 6 출력 


log(range_add(L.range(4))); // 6

위 두 연산은 모두 6으로 같은 결과가 나온다.

하지만 연산 속도는 다르다.

function test(name, time, f) {
	console.time(time);
  	while(time--){
  		f();
    }
  	console.timeEnd(time);
}

  test("range ", 10, () => reduce(add, range(100000)))
  test("L.range", 10, () => reduce(add, L.range(100000)))   

take

take함수는 l로 숫자와 , iter 이터러블을 받아서 l만큼까지만 이터러블을 순회하며 결과를 반환하는 함수이다.

const take = (l, iter) => {
	let res = [];
  	for (const a of iter) {
      res.push(a);
    	if (res.length === l){
         	return res;
        }
    }
}

log(take(3, range(1000))) // [0,1,2] 출력 
log(take(3, L.range(1000))) // [0,1,2] 출력   

range의 경우는 [0,1.....,999] 배열을 먼저 만들고 0,1,2만을 뽑아서 리턴하게 된다.

하지만 L.range는 take에서 for of를 돌며 인자를 뽑을때 값을 만들어 내기 때문에 0,1,2 까지만 값이 만들어지고 나머지 요소는 만들어지지 않게 된다.

즉, 연산이 필요한 시점에 값을 만들어 사용하므로 유리하게 사용할 수 있다.

curry 적용

가독성을 위해 take에 curry를 적용하고 go를 적용할 수 있다.

const take = curry((l, iter) => {
	let res = [];
  	for (const a of iter) {
      res.push(a);
    	if (res.length === l){
         	return res;
        }
    }
})

curry를 적용했으므로 함수에 두개의 인자가 들어올때까지 대기했다가 인자가 두개가 될 때, 함수가 실행하게 된다.

go (
  L.range(1000),
  take(4),
  reduce(add)
  ) // 6 출력 
profile
내가 될 거라고 했잖아

0개의 댓글