在这个简单的程序中,它会打印从1到10000000的所有数字。有一个Haskell版本和一个C版本,为什么Haskell版本如此缓慢,有哪些命令可以帮助学习如何提高Haskell程序的性能?
下面是一个包含所有必要细节以重现我的激动人心事件的报告,当制作报告时,打印出所有源代码,包括Makefile的源代码。
下面是一个包含所有必要细节以重现我的激动人心事件的报告,当制作报告时,打印出所有源代码,包括Makefile的源代码。
$ make -B report
cat Foo.hs
import Data.Foldable
main = traverse_ print [1..10000000]
cat Fooc.c
#include <stdio.h>
int main()
{
for (int n = 0; n < 10000000; ++n)
{
printf("%d\n", n+1);
}
}
ghc -O3 Foo.hs -o Foo
time ./Foo | tail -n1
3.45user 0.03system 0:03.49elapsed 99%CPU (0avgtext+0avgdata 4092maxresident)k
0inputs+0outputs (0major+290minor)pagefaults 0swaps
10000000
cc -O3 Fooc.c -o Fooc
time ./Fooc | tail -n1
0.63user 0.02system 0:00.66elapsed 99%CPU (0avgtext+0avgdata 1468maxresident)k
0inputs+0outputs (0major+63minor)pagefaults 0swaps
10000000
cat Makefile
.PHONY: printFoo printFooc printMakefile
printFoo: Foo.hs
cat $^
printFooc: Fooc.c
cat $^
printMakefile: Makefile
cat $^
Fooc: CFLAGS=-O3
Fooc: Fooc.c
Foo: Foo.hs
ghc -O3 $^ -o $@
.PHONY: timeFoo timeFooc
timeFoo: Foo
time ./$^ | tail -n1
timeFooc: Fooc
time ./$^ | tail -n1
.PHONY: report
report: printFoo printFooc timeFoo timeFooc printMakefile
Int64
或Int
,而不是Integer
。 - Willem Van Onsemprint (last [1::Int .. 10000000])
将仅打印列表的最后一个元素(同时使用Int
而不是其他人建议的Integer
)。 - duplodeInteger
和常量大小类型与这里的性能问题关系不大,未装箱的列表结构也一样。事实是,在 C 语言中print
确实比printf
慢得多。但是 a) 如果你关心打印的性能,那么这相当愚蠢,因为如果你的数字太多了,它会很重要,那就不要打印它们!(对于大数据量总是使用二进制格式。)... - leftaroundabout