20

I'm new to f#. I downloaded the Visual Studio 2010 shell and the F# ctp and wrote a small hello world script with the following code

printfn "Hello World"
let _ = System.Console.ReadLine()

This takes around 13 to 15 seconds to compile which is very slow compared to running a similar C# script(which takes around 2 secs). I'd like the F# script to compile faster so that my development(i.e. experimentation) time would be reduced, I don't care for the runtime performance.

Is there any way to make the F# script compile faster, maybe turn on/off some Build settings in Visual Studio or something like that?

FYI, I'm using a 4 year old pentium 4, 1.5 gb RAM machine, if that helps.

user547057
  • 313
  • 3
  • 10

3 Answers3

40

I have no idea how fast a Pentium 4 should compile that "hello world" program, but 15 seconds strikes me as pretty slow. I once had similar speed problems with a VS 2010 Beta and the problem turned out to be that Visual Studio and the F# compiler weren't yet properly NGENed.

Normally, the Visual Studio install should make sure that everything gets NGENed, but maybe something went wrong. You can check if the F# compiler was NGENed with the following command in a console window with admin rights:

cd "C:\Program Files\FSharp-2.0.0.0\bin"
c:\windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe display fsc.exe

If the result of that shows that the native image of fsc.exe is still pending, you could force the compilation with:

c:\windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe executeQueuedItems

Note: I'm not sure which version of the F# compiler you're using exactly. The one used by the full install of VS2010 is the one in C:\Program Files\Microsoft F#\v4.0 (or C:\Program Files (x86)\Microsoft F#\v4.0 on 64-bit machines). So, if you use that one, you have to cd into that folder instead of the C:\Program Files\FSharp-2.0.0.0\bin folder.

GregC
  • 7,737
  • 2
  • 53
  • 67
Stephan Tolksdorf
  • 3,062
  • 21
  • 28
  • 2
    I just had the same issue. Hard to believe this is a still a problem – Michael Sondergaard Mar 20 '12 at 02:18
  • It could take time and space on disk to compile all queued items. Probably one should specify priority at the end `c:\windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe executeQueuedItems 3` to compile only libs with same priority as fsc.exe or use `ngen install` command only for fsc.exe. – V.B. Dec 07 '13 at 09:01
  • 1
    I just had this problem when compiling a simple F# 3.1 application in a newly installed VS2013 on Win8. Your answer helped, thanks! – Andreas Ågren Dec 08 '13 at 15:39
6

Unfortunately there isn't much you can do -- the F# compiler is just slower than the C# compiler. But let me explain why:

Why the F# compiler is slower than the C# compiler

First, the F# compiler is written on .NET, the C# compiler is written in C++. While this alone isn't a death sentence to perf, it does make a difference. Second, the C# compiler is 10+ years old. There has been a lot of time to tune and optimize it -- both the compiler itself and the .NET runtime. The .NET JIT engine has been fine-tuned for C#/VB.NET and not F#. Functional programming requires a lot of short-lived objects, which translates to different type of GC behavior.

But the real reason why the F# compiler is noticeably slower than the C# compiler is because it is doing more work than the C# compiler. In C# you provide all of the type information, which in a way is you doing work for the compiler. F# on the other hand does type inference for you, which while saving you from the burden of annotation does require additional CPU time.

What you can do

I recommend you download the Visual Studio 2008 shell and use F# targeting the .NET Framework 2.0. Unless you need something that is in Visual Studio 2010 or CLR 4.0 only, you will be fine on Visual Studio 2008. The F# language functions the exact same. The only difference, IIRC, is in what types certain things compile to. For example, there is a Tuple<_> type built into CLR 4.0, but when targeting CLR 2.0 the tuple type defined in FSharp.Core.dll is used.

Visual Studio 2010 offers a lot of slick bells and whistles, such as a WPF-based code editor. However, those niceties consume a lot of RAM and in your case it sounds like you can live without them.

Chris Smith
  • 18,244
  • 13
  • 59
  • 81
  • hi, Thanks for answering. I'm downloading the VS2008 shell and F# for .net 2 and i'll see if things improve. In case it doesn't, I think i'll put off trying to learn F# for 3 months, since i'll be getting a 4 Gb ram, i5 powered laptop by then and hopefully the compile time'll get reduced. I'll leave the question open for now, just in case someone comes up with a solution or better alternative. – user547057 Jan 15 '11 at 04:47
  • I installed vs2008 and there's been no improvement in the compile speed. I'll have to wait a while, I guess :) – user547057 Jan 15 '11 at 06:56
  • hi, I unaccepted your answer and accepted Stephan Tolksdorf's, because his suggestions worked. Hope you don't mind. – user547057 Jan 15 '11 at 13:10
  • 3
    I think you'll find that type inference generally improves compilation speed in practice because parsing is so much slower than type inference. OCaml is certainly over an order of magnitude faster than most optimizing C++ compilers and the F# compiler. – J D Jan 16 '11 at 19:08
  • using an obsolete version of visual studio isn't a good solution, especially since VS 2008 is now 8 years old. Probably better idea to optimize the code, isolate the issue and resolve pain-points directly. – FistOfFury Aug 17 '16 at 14:44
5

Note also that you can use F# Interactive to evaluate snippets of code or scripts, and since the FSI window in VS stays open, it is much faster (the startup time for fsc.exe is bad).

Brian
  • 117,631
  • 17
  • 236
  • 300
  • I've tried the fsi interactive for evaluating small snippets and it's okay, but having to type ;; all the time and lack of automatic indentation is somewhat inconvenient for larger snippets. Thanks. – user547057 Jan 15 '11 at 05:37
  • 7
    Note that the typical workflow for FSI in VS is to type code into a VS file as normal, but then highlight snippets and press alt-enter to send them to the interactive window. If you are typing ;; or typing directly into the window, you are not in the most typical workflow. – Brian Jan 15 '11 at 09:23
  • I'll keep that tip in mind, though i'll probably won't use it often. – user547057 Jan 15 '11 at 13:22
  • 1
    @user547057: For larger snippets, use `#load`. One of our clients now have their testers running tests against thousands of lines of code from F# interactive. – J D Jan 16 '11 at 19:00