2013-07-23 6 views
20

Haskell ma wiele narzędzi do debugowania czasu prowadzony problemy z wydajnością, ale jakie narzędzia/reguły kciuka istnieć do debugowania czasie kompilacji problemy wydajności?debugowania kompilacji problemy z wydajnością czasowych spowodowanych ograniczeniem GHC za solver

W szczególności, solver w niektórych moich kodach trwa wiecznie (od 1-2 sekund do kilku minut). Jestem prawie pewien, że wynika to z tego, w jaki sposób używam rodzin typów w ograniczeniach, ale nie mam pojęcia, jakie rzeczy są w tym kontekście drogie, ani jak sprawdzić, gdzie zajmuje się narzędzie rozwiązywania problemów. Domyślam się, że jedna z moich operacji na listach typów przyjmuje czasy kwadratowe, a nie liniowe.

Zobaczmy przykład, dlaczego podejrzewam, że rozwiązuje ograniczenia. W moich plików, mam kod, który wygląda następująco:

class ExampleClass a where 
    type ExampleType a 
    f :: ExampleType a -> a 

data ExampleData (xs :: [a]) = ... 

instance 
    (Constraint1 
    , Constraint2 
    , ... 
    ) => ExampleClass (ExampleData xs) 
     where 
    type ExampleType (ExampleData xs) = Int 
    f = undefined 

Kiedy bardzo szybko załadować ten plik na ghci

ghci> :l Example.hs 

kompilacja dzieje, dużo mniej niż 1 sekundę. Potem wykonać następujący wiersz:

ghci> let test = f Int :: ExampleData 

Nie rzeczywisty obliczenia się dzieje, ale to nadal trwa bardzo długo. Im więcej ograniczeń w deklaracji instancji ExampleData, tym dłużej trwa. (W rzeczywistości ocenianie testu następuje później.) Najlepszym sposobem, w jaki zorientowałem się, jak rozwiązać te problemy z wydajnością, jest komentowanie ograniczeń jeden po drugim i sprawdzanie, które z nich powodują spadek wydajności. Jest to jednak bardzo czasochłonne, a gdy ograniczenia te dotyczą rodzin złożonych, nie jest to aż tak bardzo pouczające.

Czy istnieje zatem lepsze podejście do debugowania tego problemu?


Edytuj: Okazuje się, że odkryłem bug in GHC. Istnieje skrypt związany z błędem, który demonstruje, że narzędzie do rozwiązywania ograniczeń bierze kwadratowy czas na dane wejściowe, które powinny być liniowe.

+0

Zakładam, że próbowałeś skompilować GHC z włączonym profilowaniem i używaniem tego? –

+0

@BoydStephenSmithJr. Nigdy wcześniej nie kompilowałem GHC, nie mówiąc już o kompilacji włączonej. Czy istnieje samouczek na temat korzystania z tej funkcji? –

+1

[Building GHC] (http://ghc.haskell.org/trac/ghc/wiki/Building) jest prawdopodobnie dobrym zasobem i istnieje nawet sekcja dotycząca testowania porównawczego GHC, chociaż nie wiem, czy zawiera ona profilowanie. –

Odpowiedz

7

Za to, co warto, można oceniać ograniczenia pojedynczo za pomocą: rodzaju! aby sprawdzić, jak długo to potrwa, zamiast konieczności komentowania ich indywidualnie.

Powiązane problemy