I want to improve my haskell skills of writing really performant code (coming from a C/C++ Background this is important for my ego :D).
So I have written two functions to calculate Pi by the Leibnitz Formula (its not about calculation pi, it was just an example):
calcPiStep k = (if even k then 4.0 else -4.0) / (2.0*fromIntegral k + 1.0)
calcPiN n = foldl (\p x -> p + calcPiStep x) 0.0 [0..n]
calcPiInf = toinf [0..] 0
where
toinf = \(x:xs) l -> do
let curr = l + calcPiStep x
curr:toinf xs curr
calcPiInf constructs a infinite List by recursion. calcPiN with a foldl and a lambda with n iterations.
I have found that calcPiInf is faster than calcPiN AND does not run into a stack overflow for too large numbers. First question: is this just because of lazy evaluation?
Secondly I wrote a corresponding C++ Program:
using namespace std;
double calcPi(int n){
double pi = 0;
for(size_t i = 0; i < n; i++){
pi += 4.0*(i%2 == 0?1:-1)/(2.0*i + 1.0);
}
return pi;
}
int main(){
std::cout.precision(10);
cout << calcPi(5000000) << endl;
}
Which is far faster than my Haskell Solution. Is it theoretically possible to rewrite my Haskell Code to achieve a similar performance as in C++?
foldlis never a good idea, andfoldl'would be an improvement.::Double, 2) never usefoldl, usefoldl'for computing numeric values, 3) avoid GHCi, compile with ghc and-O2.