2011-08-29 17 views
8

Estoy leyendo 512^2 espacios dobles delimitados en blanco escritos en un archivo de texto en mi programa Erlang al conectarlos a stdin.¿Cómo es que mi IO funciona tan lentamente en Erlang?

En Erlang esto toma 2m25s, en un programa Haskell equivalente lleva 3s, así que debo ir en contra de la forma Erlang de hacerlo de alguna manera.

¿Estoy usando las primitivas IO de Erlang de una manera estúpida, o hay algún otro problema con mi programa?

Tenga en cuenta que no me importa el orden de los valores en la lista resultante, por lo que no hay operación inversa.

Erlang:

-module(iotest). 

-import(io). 

-export([main/0]). 

main() -> 
    Values = read(), 
    io:write(Values). 

read() -> read([]). 

read(Acc) -> 
    case io:fread("", "~f") of 
     {ok, Value} -> read([Value | Acc]); 
     eof -> Acc 
    end. 

Haskell:

module IOTest (
    main 
) where 

main :: IO() 

main = do 
    text <- getContents 
    let values = map read (words text) :: [Double] 
    putStrLn $ show values 
    return() 

Muchas gracias por cualquier ayuda.

+0

También parece que el programa Erlang generará la lista de números en orden inverso. – augustss

Respuesta

9

No, no está usando Erlang IO de manera estúpida. Es un problema con Erlang IO que no es conocido por ser rápido. Erlang es ampliamente utilizado para escribir servidores, por lo que el IO orientado con soajamiento está muy bien ajustado. El archivo orientado a bloques IO no es tan malo, pero usar el módulo io para trabajar con stdin no funciona bien. Erlang no es ampliamente utilizado para este tipo de trabajo. Si necesita este tipo de operaciones, debe escribir su propia rutina de entrada especializada. Tiene dos opciones: allí

  1. uso io para la lectura de archivos en modo raw y binarios y luego dividir la entrada utilizando el módulo binario y luego usar list_to_float/1 para la conversión.
  2. uso rutinario de lectura entrada estándar orientado puerto especializado (como se puede ver por ejemplo en http://shootout.alioth.debian.org/u64q/program.php?test=regexdna&lang=hipe&id=7 nota read/0 función y -noshell-noinput parámetros de invocación vm) y luego continuar como en la primera opción.

En opinión mía (y de la mía experiencia previa) mayor impacto en su caso proviene del uso de rutina de la entrada de lectura como de flotación decodificación secundada por lenta (repetido) io invocación, pero necesitaría algunos perfiles no trivial para probar eso.

+0

Gracias. He modificado mi programa para que se ejecute en dos fases, donde el primero lee el archivo y luego lo guarda como un término de Erlang. Cuando realmente ejecuto mi programa, ahora lee el término de Erlang, que puede hacer en segundos. –

Cuestiones relacionadas