나는 머리카락을 되찾기 위해 노력하고 있으며, 무엇이 빠르고 느리게하는지, 그리고 나는 이것에 대해 조금 혼란스러워합니다.무한한 목록을 사용할 때 실행 속도가 느려짐
필자는 특정 값까지 소수 목록을 생성하는 함수의 두 가지 구현을 가지고 있습니다. 제 직선 하스켈 위키 오프이다
primesTo :: (Ord a, Num a, Enum a) => a -> [a]
primesTo m = eratos [2..m] where
eratos [] = []
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..m])
두번째는 동일하지만 내부적 무한리스트를 사용하여 다음 두 경우
primes2 :: (Ord a, Num a, Enum a) => a -> [a]
primes2 m = takeWhile (<= m) (eratos [2..]) where
eratos [] = []
eratos (p:xs) = p : eratos (xs `minus` [p*p, p*p+p..])
마이너스 함수이다 :
minus :: (Ord a) => [a] -> [a] -> [a]
minus (x:xs) (y:ys) = case (compare x y) of
LT -> x : minus xs (y:ys)
EQ -> minus xs ys
GT -> minus (x:xs) ys
minus xs _ = xs
후자의 구현은 이전보다 훨씬 느리고 (~ 100x), 나는 이유를 알지 못합니다. 나는 haskell의 게으른 평가가 그들을 후드 아래에서 꽤 동등하게 만들 것이라고 생각했을 것이다.
이것은 분명히 질문의 목적을 위해 축소 된 테스트 케이스입니다. 실생활에서 최적화는 아무런 문제가되지 않지만 (필자는 왜 그것이 필요한지는 모르겠지만) 나에게 무한한 것을 생성하는 함수 소수 목록은 유한 목록보다 일반적으로 더 유용하지만 작업 속도가 느립니다.
참고 : 목록 중 하나가 무한 인 경우를 테스트 할 경우이 조금 더 나은를 탐색 할 수 있습니다. 생성 된 Core와 C를 살펴보면 차이점을 볼 수 있습니다. 그러나 간단히 말해서 알고리즘 적으로 생각하면 차이는 무한리스트 버전이 소수보다 m + 1 작업이 적게되는 "겹침"작업을 수행한다는 것입니다. m에 대해 두 번, m + 1에 대해. 그러나 당신이 그 일을 필요로하지 않는다면, 그것을하지 않는 것이 좋습니다. 따라서이 알고리즘을 사용하면 필요한 최대 값을 미리 알고 있다면 작업을 저장할 수 있습니다. – misterbee
비슷한 문제가있는 다른 문제 + 알고리즘을 찾기위한 연습으로 밝혀 줄 것입니다. – misterbee