【发布时间】:2014-02-19 22:45:46
【问题描述】:
我正在学习 Haskell。我的兴趣是将它用于个人计算机实验。现在,我正在尝试看看 Haskell 的速度有多快。许多人声称与 C(++) 相当,如果这是真的,我会非常高兴(我应该注意,我将使用 Haskell,无论它是否快速,但快速仍然是一件好事)。
我的测试程序用一个非常简单的算法实现了 π(x):素数将结果加 1。素数在 1 和 √x 之间没有整数除数。这不是一场算法大战,这纯粹是为了编译器性能。
Haskell 在我的计算机上似乎慢了大约 6 倍,这很好(仍然比纯 Python 快 100 倍),但这可能只是因为我是 Haskell 新手。
现在,我的问题是:如何在不改变算法的情况下优化 Haskell 实现? Haskell 的性能真的与 C 相当吗?
这是我的Haskell 代码:
import System.Environment
-- a simple integer square root
isqrt :: Int -> Int
isqrt = floor . sqrt . fromIntegral
-- primality test
prime :: Int -> Bool
prime x = null [x | q <- [3, 5..isqrt x], rem x q == 0]
main = do
n <- fmap (read . head) getArgs
print $ length $ filter prime (2:[3, 5..n])
这是我的C++ 代码:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
bool isPrime(int);
int main(int argc, char* argv[]) {
int primes = 10000, count = 0;
if (argc > 1) {
primes = atoi(argv[1]);
}
if (isPrime(2)) {
count++;
}
for (int i = 3; i <= primes; i+=2) {
if (isPrime(i)){
count++;
}
}
cout << count << endl;
return 0;
}
bool isPrime(int x){
for (int i = 2; i <= floor(sqrt(x)); i++) {
if (x % i == 0) {
return false;
}
}
return true;
}
【问题讨论】:
-
你编译你的代码优化了吗?
-
在使用 GHC 编译时,您需要使用
-O2。 LLVM 位应该与它没有太大关系(不完全确定,我从未将它主要用作 Windows 开发人员)。 -
因此,您通过运行没有数据结构甚至任何不可预测分支的程序,将函数式编程系统与具有显式内存管理的命令式系统进行比较。对了,别忘了
-fprofile-generate和-fprofile-use。 -
顺便说一句,当我看到那些 sqrt/floor 计算时,我的眼睛很痛。检查
q <= sqrt(x)是否可以表达q*q <= x所以你有它:一个整数乘法与几个浮点指令。 -
@Ingo: ... 其中一个是完全不需要的 (i
标签: c++ performance haskell