하스켈에서 재귀 함수를 메모하는 가장 빠른 방법은 무엇입니까?하스켈에서 가장 효율적으로 메모를하는 방법은 무엇입니까?
배경 : 최근 저는 하스켈에서 프로젝트 오일러 문제를 해결했습니다. 많은 사람들은 재귀 적으로 정의 된 조합 또는 숫자 이론적 함수, 예를 들어 피보나치 수의 많은 계산을 요구합니다. 성능이 현저히 향상되면 이러한 기능을 메모하면 즉, 나중에 사용하기 위해 결과가 캐싱됩니다.
이 문제에 대한 많은 해결책을 보았습니다. 가장 우아한 것 같습니다 this. 하나는 Data.IntMap (또는 해시 테이블) 및 상태 모나드를 사용합니다. this answer에서 제안 된 트리 기반 솔루션은 매우 보편적 인 것처럼 보입니다. 다른 예를 들면 this blog post을 참조하십시오. 내장 함수를 사용하는 다른 솔루션을 보았습니다. 섹션 2에 fix
이있는 here이 있으며 추가 작업없이 컴파일러가 massaged into memoizing 일 수 있습니다. 또한 prebuilt solutions 몇 개가 있습니다.
Project Euler에서 사용되는 종류의 함수에 대해 어떤 메모 작성 방법이 가장 빠른지 궁금합니다. 내 직관은 해시 테이블이 명령형 언어에서 선호하는 사전 구조 인 것처럼 보이기 때문에 해시 테이블 라이브러리가 있다고 말합니다. 순수 기능 트리 솔루션은 시원하지만 내 인터넷 검색, 그들은 몇 가지 의견이 질문에 대답하기 너무 광범위하고, 동의 반사에 말했다 strictly worse than hash tables in terms of asymptotic performance.
편집
있어 나에게 말한다. 따라서 피보나치 수를 재귀 적으로 계산하는 함수와 카탈로니아의 숫자를 재귀 적으로 계산하는 함수의 두 가지 함수를 기억해 보겠습니다. 큰 n에 대해 여러 번이 함수를 계산하고 싶습니다.
나는 이것들에 대한 명확한 공식이 있음을 알고 있지만 무시해 보도록하겠습니다. 여기서 중요한 점은 memoization 기술을 벤치마킹하기 위해 그것을 사용하는 것이기 때문입니다.
이진 검색 나무 [처럼'IntMap'] (https://github.com/haskell/containers/blob/master/Data/IntMap/Internal.hs#L347-L352)입니다 _asymptotic_ 성능 측면에서 해시 맵보다 느립니다. 그러나 Asymptotics는 모든 것이 아닙니다. 'IntMap'은 해싱의 오버 헤드를 피하고, 지속적인 방식으로 사용될 때 잘 동작하는 등의 여러 가지 바람직한 특성을 가지고 있습니다. 일반적인 사용법의 경우, IntMap의 성능은 해시 테이블과 경쟁적입니다. –
문제에 따라 다릅니다. 배열이 적절한 경우, 예를 들어 범위의 모든 값에서 함수를 평가해야하는 경우와 같이 가장 효율적인 선택 일 수 있습니다. –
참고로, 링크중인 마지막 스택 오버 플로우 응답은 Jon Harrop에 의해 작성되었습니다. [여기] (https://www.reddit.com/r/haskell/comments/4ogle3/post_about_the_disadvantages_of_functional/d4clabv/)는 @sclv가 필자에게 쓴 글은 적절하다고 생각합니다. – Alec