61

Is there any C#/F# performance comparison available on web to show proper usage of new F# language?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689
Vijesh VP
  • 4,508
  • 6
  • 30
  • 32

3 Answers3

61

Natural F# code (e.g. functional/immutable) is slower than natural (imperative/mutable object-oriented) C# code. However, this kind of F# is much shorter than usual C# code. Obviously, there is a trade-off.

On the other hand, you can, in most cases, achieve performance of F# code equal to performance of C# code. This will usually require coding in imperative or mutable object-oriented style, profile and remove bottlenecks. You use that same tools that you would otherwise use in C#: e.g. .Net reflector and a profiler.

That having said, it pays to be aware of some high-productivity constructs in F# that decrease performance. In my experience I have seen the following cases:

  • references (vs. class instance variables), only in code executed billions of times

  • F# comparison (<=) vs. System.Collections.Generic.Comparer, for example in binary search or sort

  • tail calls -- only in certain cases that cannot be optimized by the compiler or .Net runtime. As noted in the comments, depends on the .Net runtime.

  • F# sequences are twice slower than LINQ. This is due to references and the use of functions in F# library to implement translation of seq<_>. This is easily fixable, as you might replace the Seq module, by one with same signatures that uses Linq, PLinq or DryadLinq.

  • Tuples, F# tuple is a class sorted on the heap. In some case, e.g. a int*int tuple it might pay to use a struct.

  • Allocations, it's worth remembering that a closure is a class, created with the new operator, which remembers the accessed variables. It might be worth to "lift" the closure out, or replaced it with a function that explicitly takes the accessed variables as arguments.

  • Try using inline to improve performance, especially for generic code.

My experience is to code in F# first and optimize only the parts that matter. In certain cases, it might be easier to write the slow functions in C# rather that to try to tweak F#. However, from programmer efficiency point of view makes sense to start/prototype in F# then profile, disassemble and optimize.

Bottom line is, your F# code might end-up slower than C# because of program design decisions, but ultimately efficiency can be obtained.

svick
  • 236,525
  • 50
  • 385
  • 514
Stefan Savev
  • 1,319
  • 12
  • 12
  • 3
    Interesting points, but you'd need to check on more than just one runtime; with CLI 2, x86 and x64 had very different tail-call; it has obviously been beefed up in part due to supporting F#, but this may skew C# profiles. – Marc Gravell Jan 02 '10 at 22:06
  • 9
    "This will usually require coding in imperative or mutable object-oriented style". No, you want mutation for performance but you must *avoid* object-oriented style in favour of Fortran-style. OOP is slow too... – J D Mar 28 '11 at 22:27
  • 1
    If they really need speed, I think they should consider assembly language over anything. – Little Jack Sep 05 '11 at 15:51
  • 3
    what is references (vs. class instance variables)? – colinfang May 01 '13 at 14:04
  • 3
    F# is not slower than C#, nor the other way around. Languages have no execution performance. What we're talking about is the efficiency of the compilers. The more advanced compiler technology becomes, the better the chance that higher level languages can be optimized more than lower level languages, since you can generally reason more about functional source. We are at a point now where programming in functional languages enters mainstream business, and one reason is that their execution speed is closing in on imperative languages. We can hope they will overtake within a decade. – Bent Tranberg Sep 16 '15 at 07:10
  • 1
    @BentTranberg Wrong. Languages define concepts, which then need to be mapped to programs that run on actual hardware. Some of these concepts are harder to run than others. For example, if I designed a language with just one instruction to automatically understand and solve any problem, not only would it be near impossible to implement, it'd also be ***very, very, VERY slow***; and that wouldn't be the compiler's problem, it'd be the language's. – Arshia001 Feb 06 '19 at 07:39
  • BentTranberg is right. Arshia001 too. Language has not inherent performance, of course; it depends on the optimizations that the compiler can do. At the same time, obviously, an imperative language is more easier to optimize because it's more similar to how hardware works. This is why functional language has been not used on actual industry for years. Haskell is a good example of this changing, as it's compiler can do monstruous optimizations, compiling code to near C speed. – Mateus Felipe Sep 13 '19 at 12:45
24

See these questions that I asked recently:

Community
  • 1
  • 1
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
11

Here are a few links on (or related to) this topic:

What I seem to remember from another post on Robert Pickering's blog (or was it Scott Hanselman?) that in the end, because both are sitting on the same framework, you can get the same performance from both, but you sometimes have to 'twist' the natural expression of the language to do so. In the example I recall, he had to twist F# to get comparable performance with C#...

Benjol
  • 63,995
  • 54
  • 186
  • 268
  • 5
    The converse is also true if you benefit from features unique to F#, such as `inline`. – J D Apr 21 '10 at 15:20