나는 사이의 개념 차이를 이해 reduce
하고를 apply
:
(reduce + (list 1 2 3 4 5))
; translates to: (+ (+ (+ (+ 1 2) 3) 4) 5)
(apply + (list 1 2 3 4 5))
; translates to: (+ 1 2 3 4 5)
그러나 어느 것이 관용적 클로저입니까? 어떤 식 으로든 다른 점에서 많은 차이가 있습니까? 내 (제한된) 성능 테스트에서 reduce
조금 더 빠릅니다.
답변
reduce
그리고 apply
물론 단지 동등한있는 가변 인수에 대응 케이스에 모든 인수를 볼 필요가 연관 기능 (궁극적 인 결과의 측면에서 반환). 그것들이 결과적으로 동등 할 때, 나는 그것이 일반적으로 apply
완벽하게 관용적이지만, 많은 경우 reduce
에 동등 하지만 눈 깜박임의 일부를 깎을 수 있다고 말하고 싶습니다 . 다음은 이것을 믿는 나의 근거입니다.
+
reduce
변수 자체의 경우 두 가지 이상의 인수로 구현됩니다. 실제로, 이것은 가변적, 연관 기능 reduce
을 수행하기 위해 엄청나게 합리적인 “기본”방법처럼 보입니다. 아마도 internal-reduce
마스터에서 최근에 비활성화 된 1.2 참신을 통해 일을 가속화하기 위해 최적화를 수행 할 가능성이 있습니다. 바라건대 미래에 다시 도입되기를 희망합니다. vararg의 경우에 도움이 될 수있는 모든 기능을 복제하는 것은 어리석은 일입니다. 이러한 일반적인 경우 apply
에는 약간의 오버 헤드가 추가됩니다. (실제로 걱정할 필요는 없습니다.)
반면에 복잡한 함수는 일반적으로 구현할 수없는 최적화 기회를 활용할 수 있습니다 reduce
. 다음 apply
당신이 그 동안 활용할 수 있도록 것입니다 reduce
실제로 느려질 수 있습니다. 실제로 후자의 시나리오 발생하는의 좋은 예에 의해 제공된다 str
: 그것은 사용 StringBuilder
내부적의 사용으로 크게 도움이됩니다 apply
보다는 reduce
.
그래서, apply
의심 스러울 때 사용한다고 말하고 싶습니다 . 그리고 그것이 당신에게 아무것도 사지 않는다는 것을 알게되면 reduce
(그리고 이것은 곧 바뀔 것 같지 않다), reduce
당신이 그것을 느끼면 그 불필요한 불필요한 오버 헤드를 면도 하는 데 자유롭게 사용 하십시오.
답변
이 답변을보고있는 초보자
에게는 조심하지 마십시오.
(apply hash-map [:a 5 :b 6])
;= {:a 5, :b 6}
(reduce hash-map [:a 5 :b 6])
;= {{{:a 5} :b} 6}
답변
의견이 다양하다-더 큰 Lisp 세계에서, reduce
더 관용적 인 것으로 간주된다. 먼저, 이미 논의 된 가변성 문제가 있습니다. 또한 일부 공통 Lisp 컴파일러는 apply
인수 목록을 처리하는 방식으로 인해 매우 긴 목록에 적용될 때 실제로 실패 합니다.
그러나 내 서클의 클로저리스트들 사이 apply
에서이 경우에 사용하는 것이 더 일반적 인 것 같습니다. 나는 더 쉽게 이해하고 선호합니다.
답변
+는 여러 인수에 적용 할 수있는 특별한 경우이므로이 경우에는 차이가 없습니다. Reduce는 임의의 긴 인수 목록에 고정 된 수의 인수 (2)를 예상하는 함수를 적용하는 방법입니다.
답변
나는 일반적으로 모든 종류의 컬렉션에서 작업 할 때 감소를 선호한다는 것을 알았습니다. 그것은 잘 수행되며 일반적으로 매우 유용한 기능입니다.
apply를 사용하는 주된 이유는 매개 변수가 다른 위치에서 다른 것을 의미하거나 초기 매개 변수가 몇 개 있지만 컬렉션에서 나머지를 얻으려는 경우입니다.
(apply + 1 2 other-number-list)
답변
이 특정 경우에는 reduce
더 읽기 쉽기 때문에 선호합니다 .
(reduce + some-numbers)
시퀀스를 값으로 바꾸고 있음을 즉시 알고 있습니다.
로 apply
I이 적용되고있는 기능을 고려해야한다 : “아, 그것은이다 +
내가 … 단일 번호를 받고 있어요, 그래서 기능”. 약간 덜 간단합니다.
답변
+와 같은 간단한 기능을 사용할 때는 실제로 어떤 기능을 사용하든 상관 없습니다.
일반적으로 아이디어는 reduce
누적 연산입니다. 누적 함수에 현재 누적 값과 하나의 새 값을 표시합니다. 함수의 결과는 다음 반복에 대한 누적 값입니다. 따라서 반복은 다음과 같습니다.
cum-val[i+1] = F( cum-val[i], input-val[i] ) ; please forgive the java-like syntax!
적용하려면 여러 스칼라 인수를 예상하는 함수를 호출하려고하지만 현재 콜렉션에 있으며 꺼내야합니다. 따라서 말하지 않고
vals = [ val1 val2 val3 ]
(some-fn (vals 0) (vals 1) (vals 2))
우리는 말할 수있다:
(apply some-fn vals)
그리고 다음과 같이 변환됩니다.
(some-fn val1 val2 val3)
따라서 “적용”을 사용하는 것은 시퀀스 주위의 “괄호 제거”와 같습니다.