2011-03-21 11 views
9

necesito para medir el tiempo de CPU de una función como la siguiente:Haskell, Medición de tiempo de CPU de una función

t <- getCPUTime 
res <- callTheFunction input 
t' <- getCPUTime 
print $ t' - t 

El problema viene de la pereza de Haskell. callTheFunction debe ser evaluado estrictamente. ¡He buscado mucho y he tratado de usar seq y $! pero sin éxito. Creo que esta debería ser una tarea bastante común. De todos modos, necesito ayuda. Gracias.

Actualización: Gracias por toda la ayuda, especialmente @FUZxxl. Me recuerda la diferencia entre WHNF (forma normal de cabeza débil) y forma normal. Haskell/Laziness ayuda a comprender la evaluación perezosa de Haskell.

Lo que necesitaba era una evaluación más. De todos modos $! o evaluar tanto funciona siempre y cuando solamente se necesita WHNF de res:

t <- getCPUTime 
res <- callTheFunction input 
evaluate res OR return $! res 
t' <- getCPUTime 
print $ t' - t 
+1

Esto no soluciona su problema de rigor (use evaluar para eso) pero para los tiempos rápidos y sucios (es decir, más simple que el criterio) puede simplemente usar el paquete timeIt: http: //hackage.haskell. org/paquete/timeit – sclv

Respuesta

7

Uso de la función evaluate :: a -> IO aControl.Exception. Evalúa su argumento para WHNF cuando se ejecuta la acción IO correspondiente. Sin embargo, debes asegurarte de que WHNF sea suficiente para tu función.

+0

Tenga en cuenta que WHNF a menudo no es suficiente. Como ejemplo, WHNF de una lista es solo los primeros contras. –

+0

Puede combinar evaluar y aplicar que. – fuz

4

Si está tratando de hacer puntos de referencia, utilice la excelente biblioteca de criterios, que está en Hackage.

8

Si está haciendo una evaluación comparativa, entonces debe usar Criterion. De lo contrario, use NFData (rnf) y bang patterns para forzar la evaluación.

+0

El problema es que, especialmente en un contexto IO, 'seq' y' rnf' a menudo no son lo suficientemente fuertes como para evaluar la expresión al grado deseado. – fuz

+0

@FUZxxl No tengo claro a qué te refieres. Si en algún momento (antes o después de la operación IO) tiene un valor de tipo 'NFData a => a', entonces los patrones de bang y' rnf' deberían ser suficientes (ciertamente mejor que WHNF para muchos casos). –

+0

Acabo de leer sobre esto. No estoy seguro. – fuz

Cuestiones relacionadas