2009-10-04 11 views
27

Jestem nowy w Haskell i chciałbym móc wykonać czas wykonania danego wywołania funkcji lub fragment kodu.Pisanie funkcji czasu w Haskell

W Clojure mogę użyć "time ':

user=> (time (apply * (range 2 10000))) 
"Elapsed time: 289.795 msecs" 
2846259680917054518906413212119868890148051... 

W Scala, mogę zdefiniować funkcję sobie:

scala> def time[T](code : => T) = { 
    | val t0 = System.nanoTime : Double 
    | val res = code 
    | val t1 = System.nanoTime : Double 
    | println("Elapsed time " + (t1 - t0)/1000000.0 + " msecs") 
    | res 
    | } 
time: [T](=> T)T 

scala> time((1 to 10000).foldLeft(1:BigInt)(_*_)) 
Elapsed time 274.292224 msecs 
res0: BigInt = 284625968091705451... 

Jak mogę napisać równowartość mojej funkcji Scala lub Clojure jest' czas "w Haskell? System.TimeIt module Znalazłem w Hackage nie jest wystarczająco ogólny, ponieważ działa tylko wtedy, gdy mierzone jest obliczenie IO. Tak więc timeIt(4 + 4) nie zadziała, tylko timeIt(print $ 4 + 4), co szybko stanie się denerwujące. Poza tym, naprawdę chcę zobaczyć, jak Haskell radzi sobie z ogólnym przypadkiem.

Dziękujemy!

Odpowiedz

22

Proszę spojrzeć na przy użyciu standardowych bibliotek dla tego:

Wystarczy użyć kryterium .


Uwaga na głębokości oceny: lenistwo oznacza, że ​​trzeba zdecydować, ile ocena chcesz mieć podczas biegu czasu. Zazwyczaj będziesz chciał zredukować swój kod do normalnej formy. Typowa czcionka NFData pozwala to zrobić za pomocą metody rnf. Jeśli ocena do zewnętrznego konstruktora jest w porządku, użyj seq na czystym kodzie, aby wymusić jego ocenę.

+0

Wpis na wiki był dokładnie tym, czego potrzebowałem, dziękuję! – dimo414

+0

Jeden +1 trafia do ciebie :) Kolejne +1 trafia do bloga Bryana O'Sullivana :) – CoR

6

Haskell jest leniwie oceniany. Jeśli twoje wyrażenie nie ma jakiegoś efektu ubocznego (zakodowanego w monosie IO), program nie musi faktycznie tłumaczyć wyrażenia na wartość, a więc nie.

Aby uzyskać znaczące dane, możesz spróbować taktowania print 4 i print expr i podjąć decyzję, aby usunąć narzut związany z formatowaniem napisów i pozycją we/wy.

5

Lazy znaczy Lazy. Czas ma znaczenie tylko wtedy, gdy znajduje się w monadach takich jak IO.

Czas NIE ma znaczenia w wyrażeniu "4 + 4" - ani w żadnym innym równaniu matematycznym. Odpowiedź po prostu jest. "Odpowiedź" na jakiekolwiek inne czyste obliczenia jest już z góry określona w chwili, gdy zostanie określone obliczenie.

Niestety, jest to "odpowiedź" na twoje pytanie. Odpowiedź, która faktycznie istniała, zanim nawet zadałeś pytanie. Istniał w 1998 roku, kiedy język został ostatecznie zdefiniowany. Fakt, że napisanie tego zajęło mi rok, nie ma znaczenia ;-)

OK, dosyć tego nonsensu !!!! (Ale jeśli powyższe jest zbyt denerwujące, to po prostu zapomnij o Haskell.)

Jeśli pakiet Kryterium jest zbyt silny, po prostu napisz test i użyj + RTS, aby go przetestować.

Jeśli chcesz być naprawdę fajny, stwórz własną monadę - taką, która razy wykona twój algorytm i otrzyma zwrot z powrotem z powrotem z wartością zwracaną przez algorytm. Powodzenia. Wszyscy na ciebie liczymy!

+1

Jednak '4 + 4' nie jest tak naprawdę funkcją, ponieważ nie pobiera żadnych danych wejściowych. Teraz \ x -> x + 4 jest funkcją. Wartość 'x' może być dowolna. Pytanie brzmi, ile czasu zajmuje czas x, aż do poznania wyniku działania funkcji. –

+0

Haskell nie został "definitywnie zdefiniowany" w 1998 roku. Haskell zawsze był w ciągłym rozwoju i tak się stało, że twórcy zdecydowali dodać znacznik "Haskell Standard" do jednej z wersji raportu Haskella. Źródło: "Historia Haskella: bycie lenistą w klasie" –