为什么我的IO在Erlang中运行得如此之慢?

时间:2011-08-29 11:22:29

标签: haskell erlang

我正在通过将它们传送到stdin来读取512 ^ 2空格分隔的文本文件中写入的双精度到我的Erlang程序。

在Erlang中,这需要2m25s,在等效的Haskell程序中花费3s,所以我必须反对Erlang以某种方式这样做。

我是否以愚蠢的方式使用Erlang的IO原语,或者我的程序还有其他问题?

请注意,我不关心结果列表中值的顺序,因此没有反向操作。

二郎:

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

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:9)

不,你没有以愚蠢的方式使用Erlang IO。这是Erlang IO的问题,众所周知,它并不是很快。 Erlang被广泛用于编写服务器,因此以socked为导向的IO非常好。面向块的文件IO并不是那么糟糕,但使用io模块处理stdin并不能很好地工作。 Erlang并没有被广泛用于这类工作。如果您需要这种操作,您应该编写自己的专用输入例程。你有两个选择:

  1. 使用io以原始和二进制模式从文件读取,然后使用二进制模块拆分输入,然后使用list_to_float/1进行转换。
  2. 使用专门的面向端口的stdin读取例程(例如,您可以在http://shootout.alioth.debian.org/u64q/program.php?test=regexdna&lang=hipe&id=7注释read/0函数和-noshell -noinput vm调用参数中看到),然后继续在第一个选项中。
  3. 在我看来(以及我之前的经验)你的案例中最大的影响来自于使用类似扫描的输入例程进行缓慢(重复)io调用的浮动解码,但需要一些非常重要的分析来证明它。 / p>