2009-10-04 24 views
27

Soy nuevo en Haskell y me gustaría poder sincronizar el tiempo de ejecución de una llamada de función determinada o un fragmento de código.Escribir una función de tiempo en Haskell

En Clojure puedo utilizar 'time ':

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

En Scala, puedo definir la función a mí mismo:

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... 

¿Cómo puedo escribir el equivalente de mi función Scala o Clojure de' tiempo 'en Haskell? El System.TimeIt module que he encontrado en Hackage no es lo suficientemente general porque solo funciona si se está midiendo un cálculo de IO. Entonces timeIt(4 + 4) no funcionaría, solo timeIt(print $ 4 + 4), que se vuelve molesto rápidamente. Además, realmente quiero ver cómo maneja Haskell el caso general.

¡Gracias!

Respuesta

22

favor buscar en el uso de las bibliotecas estándar para esto:

sólo tiene que utilizar el criterio .


Una nota sobre la evaluación a fondo: la pereza significa que tiene que decidir cuánto de evaluación que desea tener durante la carrera de tiempo. Por lo general, querrás reducir tu código a la forma normal. La clase de tipo NFData te permite hacer esto a través del método rnf. Si la evaluación para el constructor más externo está bien, use seq en su código puro para forzar su evaluación.

+0

La entrada de la wiki era exactamente lo que necesitaba, ¡gracias! – dimo414

+0

One +1 va para ti :) Otro +1 va al blog de Bryan O'Sullivan :) – CoR

6

Haskell es evaluado perezosamente. Si su expresión no tiene algún efecto secundario (como se codifica en la mónada IO o similar), entonces el programa no necesita resolver realmente la expresión a un valor, y tampoco lo hará.

Para obtener números significativos de esto, puede intentar sincronizar print 4 y print expr y tomar la diferencia, para eliminar la sobrecarga del formato de cadena y IO.

5

Lazy means Lazy. El tiempo solo es relevante cuando se encuentra dentro de una mónada como IO.

El tiempo no tiene significado en la expresión "4 + 4" - o en cualquier otra ecuación matemática. La respuesta simplemente ES La "respuesta" a cualquier otro cálculo puro ya está predeterminada en el instante en que se especifica el cálculo.

Lamentablemente, esta es la "respuesta" a su pregunta. Una respuesta que, de hecho, existía antes de que incluso plantearas tu pregunta. Existió en 1998 cuando el lenguaje fue finalmente definido. El hecho de que me tomó un año escribir esto no importa ;-)

OK, ya basta de esas tonterías !!!! (Pero si lo anterior es demasiado molesto, olvídate de Haskell.)

Si el paquete Criterion es demasiado doloroso, solo escribe un caso de prueba y usa + RTS para probarlo.

Si quieres ser realmente genial, crea tu propia mónada, una que multiplica la ejecución de tu algoritmo y devuelve el resultado al valor de retorno del algoritmo. Buena suerte. ¡Todos contamos contigo!

+1

Sin embargo, '4 + 4' no es en realidad una función, ya que no requiere información. Ahora \ x -> x + 4 es una función. El valor de 'x' podría ser cualquier cosa. La pregunta es, ¿cuánto tiempo lleva desde que se conoce x hasta que se conoce el resultado de la función? –

+0

Haskell no fue "finalmente definido" en 1998. Haskell siempre estuvo en constante desarrollo y por eso sucedió que los creadores decidieron agregar la etiqueta "Haskell Standard" a una de las versiones del Informe Haskell. Fuente: "Una historia de Haskell: ser flojo con la clase" –

Cuestiones relacionadas