91 votes

Temps d'exécution des fonctions Haskell

Existe-t-il une méthode simple pour calculer le temps d'exécution d'une fonction en Haskell ?

0 votes

Les réponses à ma question sur le critère peuvent contenir des exemples d'utilisation utiles. stackoverflow.com/questions/6637968/ .

3 votes

En outre, il s'agit d'une situation quelque peu nuancée, car les fonctions n'ont pas besoin d'être entièrement "exécutées" en Haskell. Elles doivent juste être suffisamment étendues pour obtenir la valeur requise. Prenons l'exemple de head [1..] qui prend le premier élément d'une liste infinie.

0 votes

@gatoatigrado C'est pourquoi le critère a le whnf y nf fonctions.

133voto

Rafal Points 464

La chose la plus simple est de simplement faire :set +s sur ghci Vous pouvez alors voir le temps d'exécution de tout ce que vous exécutez, ainsi que l'utilisation de la mémoire.

25 votes

Les fonctions s'exécutent cependant beaucoup plus lentement en ghci. Dans mon test, elles sont environ 10 fois plus lentes.

3 votes

Est-il possible de définir la précision du temps mesuré, par exemple en millisecondes ?

1 votes

Slower, yes, but this appears to be very valuable for demonstrating differences in time and space consumption between algorithms. For example <pre><code> slow_fib :: Int -> Integer slow_fib 0 = 0 slow_fib 1 = 1 slow_fib n = slow_fib (n-2) + slow_fib (n-1) -- vs. memoized_fib :: Int -> Integer memoized_fib = (map fib [0 ..] !! ) where fib 0 = 0 fib 1 = 1 fib n = memoized_fib (n-2) + memoized_fib (n-1) </pre></code> Where you can see the first function not only take up a LOT more time, but also several orders of magnitude more space.

30voto

Daniel Wagner Points 38831

Le site criterion paquet a été conçu spécifiquement pour faire cela bien.

11voto

MatrixFrog Points 11066

Voir si http://hackage.haskell.org/package/timeit convient à vos besoins.

7voto

Zane XY Points 524

Le benchmark du temps d'exécution de la fonction est inclus dans Critère.Mesure

par exemple, si je veux capturer le temps de someIOFunction :: IO ()

import Criterion.Measurement
main = secs <$> time_ someIOFunction >>= print

2 votes

Ceci n'est plus supporté - semble déprécié.

3voto

trevor cook Points 974

Criterion est la méthode la plus sophistiquée, bien que je l'aie trouvée difficile à démarrer, et elle semble ciblée sur les programmes de benchmarking. Je voulais calculer le temps d'exécution et utiliser ces données au sein de mon programme et il ne semble pas répondre à ce besoin, du moins ce n'est pas immédiatement apparent.

TimeIt est très simple et fait ce que je voulais, sauf qu'il ne gère pas bien les fonctions pures. Le temps retourné pour une fonction pure est le temps d'allocation du thunk (AFAIK) et même en utilisant seq il peut être difficile d'obtenir ce que vous voulez.

Ce qui fonctionne pour moi est basé sur TimeIt.

import System.TimeIt

timeItTPure :: (a -> ()) -> a -> IO (Double,a)
timeItTPure p a = timeItT $ p a `seq` return a

Dans timeItTPure p a, p est la fonction responsable de l'évaluation du résultat d'un calcul pur, a, aussi profondément que nécessaire pour obtenir le bon timing d'évaluation. Il peut s'agir d'une simple correspondance de motifs, d'un comptage de la longueur d'une liste, d'un seq de chaque élément de la liste, d'un deepseq, etc.

L'utilisation de seq est délicate. Notez que la fonction ci-dessous ne fonctionne pas comme souhaité. Haskell est une chose mystérieuse.

badTimeItTPure a = timeItT . return $ seq (p a) a

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X