Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come my IO runs so slowly in Erlang?

Tags:

haskell

erlang

I'm reading 512^2 whitespace delimited doubles written in a text file to my Erlang program by piping them to stdin.

In Erlang this takes 2m25s, in an equivalent Haskell program it takes 3s, so I must be going against the Erlang way of doing it in some way.

Am I using Erlang's IO primitives in a stupid way, or is there something else wrong with my program?

Note that I don't care about the order of the values in the resulting list, so no reverse operation.

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 ()

Thanks very much for any help.

like image 890
Steve Johnson Avatar asked Aug 29 '11 11:08

Steve Johnson


1 Answers

No, you are not using Erlang IO in stupid way. It's problem with Erlang IO which is not well known to be fast. Erlang is widely used for writing servers so socked oriented IO is excellent tuned. Block oriented file IO is not so bad, but using io module for working with stdin doesn't work well. Erlang is not widely used for this kind of work. If you need this kind of operations you should write your own specialized input routine. You have two options there:

  1. use io for reading from file in raw and binary mode and then split input using binary module and then use list_to_float/1 for conversion.
  2. use specialized port oriented stdin reading routine (as you can see for example in http://shootout.alioth.debian.org/u64q/program.php?test=regexdna&lang=hipe&id=7 note read/0 function and -noshell -noinput parameters for vm invocation) and then continue as in first option.

In mine opinion (and from mine previous experience) biggest impact in your case comes from using scan-like input routine for float decoding seconded by slow (repeated) io invocation, but it would need some nontrivial profiling to prove it.

like image 164
Hynek -Pichi- Vychodil Avatar answered Nov 13 '22 11:11

Hynek -Pichi- Vychodil