F# Performance:
I'm starting my adventure with F#. I've heard some good things about it, more so that it's target is more focused on scientific calculation, then a pure bl development, so probably it should be also faster (tail calls & new optimized Il instructions). There are some performance comparisons on F# and C# but I've decided to do my own, and get to know the language a bit (as I don't know it at all).
Notice. This post isn't about comparing performance of both C# and F# it's more what i found out learning the basics so this is by no means professional performance test (tail calls are on in F#).
So lets start with a simple fib function straight from a mathematical definition:
//F# let rec fib(n) = if n = 1 then 1 elif n = 2 then 2 else fib(n - 1) + fib(n - 2) //C# public long Fib(int n) { if (n == 1) return 1; else if (n == 2) return 2; else return Fib(n - 1) + Fib(n - 2); }
rec in F# tells the function that it will use recurrence
This version is very similar to a C# version nothing really new about it.
Wen we run it the time to calculate the sequence for n = 42 we get:
F# handles it in around 7 sec.
C# handles it in around 9 sec.
So F# is a little bit faster here, when we decompile the code (im not going to show you that) it will be clear that the F# version is shorter.
Now let's use a different aproach F# has a nice match mechanism so lets use that and lets do a signle recrrence call to fib function insted of two:
//F# let fibA(n) = let rec fibx (n, a, b) = match (n, a, b) with | (0, a, b) -> a | _ -> fibx (n - 1, a + b, a) fibx (n, 0I, 1I) //C# public long FibA(int n) { return Fibx(n, 0, 1); } private long Fibx(int n, int a, int b) { if (n == 0) return a; else return Fibx(n - 1, a + b, a); }
the 'I' on fibx call are telling the compiler to use BigIntegers.
Still we can do the same in C# by replacing the match witch switch/case. (Match is a switch/case in IL)
Now if we run the code for n = 42 we get different results:
F# handles it in around 350 ms.
C# handles it in around 5 ms (wow).
But still this code is very similar to C# in structure, so let's try doing it the F# way all the way ;-)
let fibs = Seq.unfold (fun (a, b) -> Some(a, (b, a + b) )) (1,1) let x = Seq.toList (Seq.take 42 fibs);
Now this at first can be hard to understand what's going on here, in short we build a sequence from a function that generates the data . The (1,1) are function parameters as in F# everything is a function.
So this is a 1 line implementation of the fib seqence (nice).
Again if we run the code for n = 42 we get:
F# handles it in around 300 ms.
So as far as my learning of F# goes and the performance testing for recurrence problem C# can handle it better if you cut the problem to a single recurrence call on the fib, but when applying the function from it's mathematical definition F# is faster, but I could be doing it all wrong with F# and thus the performance could be lowered.
Next on my list is writing some collection sorting in F# and learn about its data types as those could be potentially used with ADO.NET to get data in a very flexible way.
No comments:
Post a Comment