gpt4 book ai didi

haskell - Haskell 中的基本 I/O 性能

转载 作者:行者123 更新时间:2023-12-02 02:49:58 26 4
gpt4 key购买 nike

另一个微基准测试:为什么这个“循环”(用 ghc -O2 -fllvm 编译,7.4.1,Linux 64bit 3.2 内核,重定向到 /dev/null )

mapM_ print [1..100000000]

比普通的简单 for-cycle 慢约 5 倍 Cwrite(2)非缓冲系统调用?我正在尝试收集 Haskell 问题。

即使这种缓慢的 C 解决方案也比 Haskell 快得多
int i;
char buf[16];
for (i=0; i<=100000000; i++) {
sprintf(buf, "%d\n", i);
write(1, buf, strlen(buf));
}

最佳答案

好的,我的盒子上有 C 代码,根据 gcc -O3 编译运行大约需要 21.5 秒,原始 Haskell 代码大约需要 56 秒。所以不是 5 的因数,略高于 2.5。

第一个重要的区别是

mapM_ print [1..100000000]

用途 Integer s,这有点慢,因为它涉及预先检查,然后使用盒装 Int s,而 Show Int 的实例对未装箱的 Int# 是否进行转换工作s。

添加类型签名,以便 Haskell 代码适用于 Int
mapM_ print [1 :: Int .. 100000000]

将时间缩短到 47 秒,比 C 代码花费的时间多一倍。

现在,另一个很大的区别是 show产生 Char 的链表并且不只是填充连续的字节缓冲区。那也比较慢。

然后是 Char的链表s 用于填充字节缓冲区,然后将其写入 stdout处理。

所以,Haskell 代码比 C 代码做更多、更复杂的事情,因此它需要更长的时间也就不足为奇了。

诚然,希望有一种简单的方法来更直接地(因此更快)输出这些东西。但是,处理它的正确方法是使用更合适的算法(也适用于 C)。一个简单的改变
putStr . unlines $ map show [0 :: Int .. 100000000]

花费的时间几乎减少了一半,如果想要真的很快,可以使用更快的 ByteString I/O 并有效地构建输出,如 applicative's answer 中所示.

关于haskell - Haskell 中的基本 I/O 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13334074/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com