• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

"reduce 하나 보다 map + filter + reduce" 관련해서 질문드립니다~

19.06.19 15:20 작성 조회수 415

0

강사님 강의 잘 봤습니다. "reduce 하나 보다 map + filter + reduce" 관련해서 질문드릴게 있어서요.

함수형 개발 기법 중에 transducer라는 게 있는 걸로 알고 있습니다. 어느정도 개념만 알고 있어서 이와 관련해서 질문 좀 드리려고 합니다.

transducer 관련한 글을 보면 map, filter, reduce 등을 여러번 쓰는 것보다 reduce protocol을 따르는 map, filter등을 사용해서 compose(pipe)등으로

합성해서 사용하는게 많은 데이터를 다룰때 효율적이다라고 알고 있습니다(실제로 ramdajs, rxjs 등이 이러한 기법으로 만들어진걸로 알고 있구요).

강사님은 대용량 데이터를 다뤄야 할때도 reduce 하나 보다 map + filter + reduce 이렇게 사용을 하시나요?

map + filter + reduce를 사용 하는 데 퍼포먼스 상 굳이 신경쓸 정도의 손해는 없는지 다른 의견이 있으신지 궁금합니다.

 

감사합니다.

 

답변 4

·

답변을 작성해보세요.

1

답변을 덜 드린 부분이 있는데 transducer 스타일이 자원을 덜 쓴다는 것은 이론적으로 맞지만, 사실 실제 환경에서는 그냥 일반 map filter reduce 가 결과를 내는 속도만 놓고 보면 더 빠르기도 합니다. 그정도로 사실 이런 차이는 차이라고 보기 애매합니다. transducer가 이론적으로 좋다는걸 증명하려고 메모리 사이즈까지 보여주고 막 그러지만, 그래야한다는 것은 오히려 그만큼 큰 의미는 없는 것이라고 볼 수도 있습니다. 그런 '아이디어' 자체가 중요한거라고 볼 수 있을거 같습니다.

성능적으로 정말 고민해야하는 부분은 로직의 시간 복잡도 자체를 줄이는 고민이나, IO를 효율적으로 하는 법, 동시성 로직을 잘 다루는 법 등이라고 생각합니다. 대부분의 일반적인 웹 어플리케이션에서는 이런 부분에서만 의미 있는 성능 차이가 나옵니다.

감사합니다.

0

 아 넵. 머리에 쏙쏙 잘 들어오네요. 감사합니다 :)

0

또한 transducer 같은 경우도 강의에서 이야기하고자하는 '복잡한 reduce안에 if else 등의 명령형 코드를 작성하는 대신 map filter reduce 조합으로 작성하라' 하는 해법입니다.


// bad
bigArr.reduce((total, a) => {
if (a % 2) {
return total + a * a;
} else {
return total;
}
}, 0);

// cool
bigArr.reduce((total, a) => [a]
.filter(a => a % 2)
.map(a => a * a)
.reduce(a => a + b, total), 0);

감사합니다. :)

0

말씀주신 transducer 스타일의 해법들 같은 경우 큰 array를 map, filter, reduce를 거치면서 여러번 만드는거보다 표현은 map filter 를 가져가되 큰 array를 한 번도 만들지 않고자하는 컨셉이고 큰 array를 다룰 때 유리한게 맞습니다.

그런데 map, filter가 지연성을 갖도록 만든다면 역시 한 번도 큰 array를 만들지 않아 완전히 동일한 효율을 갖게됩니다. 그러므로 영상처럼 제너레이터로만든 L.map + L.filter + reduce 를 사용하게 되면 transducer 스타일과 완전히 동일한 효율이므로 더 손해가 있거나 하지 않습니다.

내부적으로 사실상 transducer 와 동일한 흐름과 순서로 코드가 실행되고 동일한 로직이 됩니다.

결과적으로 L.map + L.filter + reduce이 표현력도 훨씬 쉽고 이해하기도 쉬우면서 동일한 효율입니다.

감사합니다 :)