나는 (a, b) == (b, a) 그리고 that ((a, b), (c, d)) ==와 함께리스트에서 모든 가능한 쌍 쌍을 생성하고 싶다. ((c, d), (a, b))를 모든 a, b, c, d에 대해 계산합니다. 또한 필자가 제공하는 목록의 모든 요소는 별개라고 가정 할 수 있습니다. 프로파일 링은 실행 시간에 가까운 90 %가 지출 된 것을 알 (이것은 관용적 인의 미덕을 가지고이 목록 이해력을 어떻게 최적화 할 수 있습니까?
pairsOfPairs :: [a] -> [((a,a),(a,a))]
pairsOfPairs xs = [((w,x),(y,z)) | w <- xs, x <- xs, y <- xs, z <- xs,
w < x, y < z, w < y, w /= z, x /= y, x /= z]
하지만 매우 느립니다 :
는내가했던 가장 먼저하는 일이 목록의 이해를 기록했다 이 함수와 다른 함수에서).
느린 이유는 n 개 요소의 목록에 대해 n^4 개의 후보 쌍 쌍을 생성하지만 제한으로 인해 결국 n!/(8 * (n-4)!) 우리가 적어도 8 번 너무 많은 일을하고 있다는 것을
속도를 높이기 위해 pairsOfPairs
함수를 다시 작성하는 방법이 있습니까? 분명히 그것은 여전히 O (n^4)가 될 것이지만 나는 상수를 없애기를 희망하고 있습니다.
편집 :는 사실, 나는 거의 항상 의미, 길이 5의 목록이 함수를 호출이 결과에 팔분의 오는 = 15 개 요소가 있지만 기능은 5의 목록을 생성하는!^4 = 625 요소를 중간 단계로 사용합니다. 이러한 모든 중간 요소를 제거 할 수 있다면 약 40 배의 속도 향상을 얻을 수 있습니다!
귀하의 첫 번째 단락과 같은 선택 쌍에 의해 거의 모든 불필요한 작업을 방지 할 수 있습니다하면 해당 A = B 형 =의 C = D 암시하는 것 같다 . 나는 그것이 당신이 의미하는 것이라고 생각하지 않습니다. – dave4420
@ dave4420 '=='은 등가를 의미합니다. 즉, 쌍 (a, b)은 쌍 (b, a)과 동일하게 계산되어야하지만 a와 b는 같아야합니다. –