【发布时间】:2011-08-21 00:39:36
【问题描述】:
我一直在做一些实验,这是我发现的。考虑以下 C 程序:
int main()
{
for(int i = 0;
i < 1000000;
++i)
{}
}
以及下面的 Haskell 程序:
import System.IO
loop :: Int -> IO ()
loop n = if 0 == n then return () else loop (n-1)
main = loop 1000000
这是上述 C 程序的time 的输出:
real 0m0.003s
user 0m0.000s
sys 0m0.000s
...对于 Haskell 程序:
real 0m0.028s
user 0m0.027s
sys 0m0.000s
一开始以为gcc检测到空循环并优化出来,但是增加迭代次数后,程序的运行时间也增加了。以下是两个程序的time 的输出,迭代次数设置为 10000000:
C 版
real 0m0.024s
user 0m0.023s
sys 0m0.000s
Haskell 版本
real 0m0.245s
user 0m0.247s
sys 0m0.000s
如您所见,Haskell 程序慢了 10 倍。
问题是:Haskell 中for 循环的有效替代方案是什么?正如我们刚刚看到的,简单递归会使程序减慢大约 10 倍(这可能与尾递归优化有关)。
【问题讨论】:
-
出于好奇,优化后的c程序生成的汇编代码是否完全去掉了循环?
-
噗,
while循环。呃。 :P -
这个明显的“基准”是一场闹剧,很抱歉。在循环中什么都不做是完全不存在的用例。函数式编程中
for循环的想法确实没有意义。迭代元素以执行计算的方法将根据计算的内容而有很大差异。选择一个真实的用例,你可能会得到一个更好、更现实的答案。 -
谎言,该死的谎言和基准。
-
@Grigory Javadyan,假设您使用的是 GHC 编译器,如果您想对程序进行任何操作,您需要打开优化。例如。
ghc -O2 -fllvm用于以绩效为导向的工作。如果您的目标是观看程序静止不动,请编写一个循环并运行它。