Gibt es eine einfache Methode, um die Zeit der Funktionsausführung in Haskell zu berechnen?
head [1..]
, welches das erste Element einer unendlichen Liste nimmt.
whnf
und nf
Funktionen.
Gibt es eine einfache Methode, um die Zeit der Funktionsausführung in Haskell zu berechnen?
head [1..]
, welches das erste Element einer unendlichen Liste nimmt.
whnf
und nf
Funktionen.
Antworten:
Einfachstes Dinge einfach zu tun , :set +s
in ghci
, und dann können Sie die Ausführungszeit alles , was Sie ausführen, zusammen mit der Speichernutzung sehen.
Das criterion
Paket wurde speziell dafür entwickelt.
Überprüfen Sie, ob http://hackage.haskell.org/package/timeit Ihren Anforderungen entspricht.
Der Benchmark für die Funktionsausführungszeit ist in Criterion.Measurement enthalten
Zum Beispiel, wenn ich die Zeit von erfassen möchte someIOFunction :: IO ()
import Criterion.Measurement
main = secs <$> time_ someIOFunction >>= print
Kriterium ist die ausgefeilteste Methode, obwohl ich es schwierig fand, sie zu starten, und sie scheint auf Benchmarking-Programme ausgerichtet zu sein. Ich wollte den Ausführungszeitpunkt berechnen und diese Daten in meinem Programm verwenden, und es scheint diesen Bedarf nicht zu decken, zumindest ist dies nicht sofort ersichtlich.
TimeIt ist sehr einfach und macht das, was ich wollte, außer dass es reine Funktionen nicht gut handhabt. Die für eine reine Funktion zurückgegebene Zeit ist die Thunk Allocation Time (AFAIK), und selbst bei Verwendung von seq kann es schwierig sein, das zu bekommen, was Sie wollen.
Was für mich funktioniert, basiert auf TimeIt.
import System.TimeIt
timeItTPure :: (a -> ()) -> a -> IO (Double,a)
timeItTPure p a = timeItT $ p a `seq` return a
In timeItTPure pa ist p die Funktion, die für die Bewertung des Ergebnisses einer reinen Berechnung a verantwortlich ist, so tief wie nötig, um das gute Bewertungszeitpunkt zu erhalten. Vielleicht ist dies eine einfache Musterübereinstimmung, vielleicht zählt es die Länge einer Liste, vielleicht ist es die Folge jedes Elements in der Liste, vielleicht ist es eine Deepseq usw.
Die Verwendung von seq ist schwierig. Beachten Sie, dass die folgende Funktion nicht wie gewünscht ausgeführt wird. Haskell ist eine mysteriöse Sache.
badTimeItTPure a = timeItT . return $ seq (p a) a
https://github.com/chrissound/FuckItTimer
start' <- start
timerc start' "begin"
print "hello"
timerc start' "after printing hello"
benchmark
timerc start' "end"
end <- getVals start'
forM_ (timert end) putStrLn
Ausgänge:
"hello"
begin -> after printing hello: 0.000039555s
after printing hello -> end: 1.333936928s
Dies scheint für meinen sehr einfachen Anwendungsfall gut zu funktionieren.