为什么我的 IO 在 Erlang 中运行得这么慢?
我正在将文本文件中写入的 512^2 个空格分隔的双精度数通过管道传输到标准输入读取到我的 Erlang 程序中。
在 Erlang 中,这需要 2 分 25 秒,在等效的 Haskell 程序中,需要 3 秒,所以我必须以某种方式反对 Erlang 的做法。
我是否以一种愚蠢的方式使用了 Erlang 的 IO 原语,或者我的程序还有其他问题吗?
请注意,我不关心结果列表中值的顺序,因此没有反向操作。
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 ()
非常感谢您的帮助。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,你没有以愚蠢的方式使用 Erlang IO。这是 Erlang IO 的问题,众所周知,它的速度并不快。 Erlang 广泛用于编写服务器,因此面向 socked 的 IO 得到了很好的调整。面向块的文件 IO 并没有那么糟糕,但是使用 io 模块来处理 stdin 效果不佳。 Erlang 并未广泛用于此类工作。如果您需要这种操作,您应该编写自己的专门输入例程。您有两个选择:
list_to_float/1
进行转换。read/0
函数和-noshell
-noinput
参数),然后按照第一个选项继续。在我看来(以及根据我以前的经验),您的案例中最大的影响来自于使用类似扫描的输入例程进行浮点解码,辅之以缓慢(重复)的 io 调用,但它需要一些重要的分析来证明这一点。
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:
list_to_float/1
for conversion.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.