How well does F # perform compared to C #?

Of course, both F # and C # compile to IL, and the CLR JITter does most of the hard work, however, I wanted to know if there is something implicit in the F # language or its main libraries, which leads to less performance compared to with c #?

Also, is there anything to use functional programming in the .net framework that can make it slower compared to C #?

I'm going to sit down and measure the differences, of course, since this is really the only real way to find out for sure, but I'm just wondering if anyone has widespread knowledge on this topic.

see also

+4
source share
2 answers

Nothing internal makes one language faster than another. They both work on the CLR and, therefore, have approximately the same performance characteristics of any language that runs on the CLR. There are functions of the respective languages, although this affects performance.

Tail recursion is a great example. If you are writing an F # application that uses tail recursion, the compiler will try to rewrite it as an iterative loop, removing the recursion penalty. In addition, F # uses the op.tail IL op code to ask the CLR, if possible, to remove the penalty from the recursive stack.

This is easy to demonstrate by translating some examples of the continuation of F # into C #, and then insert huge datasets. F # will work, and C # will eventually work.

http://blogs.msdn.com/jaredpar/archive/2008/11/13/comparing-continuations-in-c-and-f-part-3-double-wrong.aspx

But this is not necessarily a drawback of C #. C # is not intended to be written with continuation, while this, of course, takes place in F #. In fact, it is not surprising that written algorithms designed for F # in C # give not very large results.

Conversely, C # iterators are usually more efficient than F # sequence expressions. The reason is that C # iterators are very efficient state machines, and F # is a continuation of the transfer.

In general, if there are no threads, if you use languages, since they are intended for use, they will have similar characteristics.

+6
source

A good example is a sieve of eratosthenes.

An employee and I wrote similar sieves in C # and F #. The performance of the C # version was almost 10 times slower than its functional counterpart, written by my colleague.

There was probably some inefficiency in the C # version that could be cleared, but the F # version was noticeably faster.

This problem can be written in a functional language.

Hope this helps some.

Edit -

Here is one example of C # using similar functionality for F # List.Partition. I will continue to search for an F # example. I have hundreds of projects in which it may be, it is just a matter of sorting all my things to find it (I keep everything that I have ever experimented with, so it can take a lot of time .. lol)

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ListPartitionTest { public static class IEnumerableExtensions { public static KeyValuePair<IEnumerable<T>, IEnumerable<T>> Partition<T>(this IEnumerable<T> items, Func<T, bool> f) { return items.Aggregate( new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(Enumerable.Empty<T>(), Enumerable.Empty<T>()), (acc, i) => { if (f(i)) { return new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(acc.Key.Concat(new[] { i }), acc.Value); } else { return new KeyValuePair<IEnumerable<T>, IEnumerable<T>>(acc.Key, acc.Value.Concat(new[] { i })); } }); } } class PrimeNumbers { public int Floor { get; private set; } public int Ceiling { get; private set; } private IEnumerable<int> _sieve; public PrimeNumbers(int floor, int ceiling) { Floor = floor; Ceiling = ceiling; } public List<int> Go() { _sieve = Enumerable.Range(Floor, (Ceiling - Floor) + 1).ToList(); for (int i = (Floor < 2) ? 2 : Floor; i <= Math.Sqrt(Ceiling); i++) { _sieve = _sieve.Where(x => (x % i != 0 && x != i)); foreach (int x in _sieve) { Console.Write("{0}, ", x); } Console.WriteLine(); } return _sieve.ToList(); } } class Program { static void Main(string[] args) { System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch(); int floor = 1; int ceiling = 10; s.Start(); PrimeNumbers p = new PrimeNumbers(floor, ceiling); p.Go(); //foreach (int i in p.Go()) Console.Write("{0} ", i); s.Stop(); Console.WriteLine("\n{0} to {1} completed in {2}", floor, ceiling, s.Elapsed.TotalMilliseconds); Console.ReadLine(); } } } 
+5
source

All Articles