2011-08-29 16 views
8

Sto leggendo 512^2 doppi delimitati da spazi bianchi scritti in un file di testo nel mio programma Erlang pipettandoli allo stdin.Come mai il mio IO funziona così lentamente in Erlang?

In Erlang questo richiede 2m25s, in un programma Haskell equivalente ci vogliono 3 secondi, quindi devo andare contro il modo Erlang di farlo in qualche modo.

Sto usando i primitivi IO di Erlang in modo stupido, o c'è qualcos'altro che non va nel mio programma?

Si noti che non mi interessa l'ordine dei valori nell'elenco risultante, quindi nessuna operazione 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() 

Grazie molto per qualsiasi aiuto.

+0

Sembra anche che il programma Erlang generi l'elenco di numeri al contrario. – augustss

risposta

9

No, non stai usando Erlang IO in modo stupido. È un problema con Erlang IO, che non è noto per essere veloce. Erlang è ampiamente utilizzato per la scrittura di server in modo che l'I/O orientato al socking sia sintonizzato in modo eccellente. Il file IO orientato ai blocchi non è così male, ma l'utilizzo del modulo io per lavorare con stdin non funziona bene. Erlang non è ampiamente utilizzato per questo tipo di lavoro. Se hai bisogno di questo tipo di operazioni dovresti scrivere la tua routine di input specializzata. Sono disponibili due opzioni: là

  1. uso io per la lettura di file in modalità raw e binaria e poi dividere ingresso utilizzando modulo binario e quindi utilizzare list_to_float/1 per la conversione.
  2. uso specializzato porta orientata lettura stdin di routine (come si può vedere per esempio in http://shootout.alioth.debian.org/u64q/program.php?test=regexdna&lang=hipe&id=7 nota read/0 funzione e -noshell-noinput parametri per VM invocazione) e poi continuare come nella prima opzione.

A parere mio (e dal mio precedente esperienza) maggiore impatto nel vostro caso viene dal usando routine di input di scansione come per float decodifica distaccati dalla lenta (ripetuta) io invocazione, ma avrebbe bisogno di un po 'di profilazione non banale per dimostrare esso.

+0

Grazie. Ho modificato il mio programma per l'esecuzione in due fasi, in cui il primo legge il file e quindi lo salva come termine Erlang. Quando eseguo effettivamente il mio programma ora legge il termine di Erlang, che può fare in pochi secondi. –

Problemi correlati