Book Image

F# High Performance

By : Eriawan Kusumawardhono
Book Image

F# High Performance

By: Eriawan Kusumawardhono

Overview of this book

F# is a functional programming language and is used in enterprise applications that demand high performance. It has its own unique trait: it is a functional programming language and has OOP support at the same time. This book will help you make F# applications run faster with examples you can easily break down and take into your own work. You will be able to assess the performance of the program and identify bottlenecks. Beginning with a gentle overview of concurrency features in F#, you will get to know the advanced topics of concurrency optimizations in F#, such as F# message passing agent of MailboxProcessor and further interoperation with .NET TPL. Based on this knowledge, you will be able to enhance the performance optimizations when implementing and using other F# language features. The book also covers optimization techniques by using F# best practices and F# libraries. You will learn how the concepts of concurrency and parallel programming will help in improving the performance. With this, you would be able to take advantage of multi-core processors and track memory leaks, root causes, and CPU issues. Finally, you will be able to test their applications to achieve scalability.
Table of Contents (15 chapters)
F# High Performance
Credits
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Preface

Introduction to debugging in F#


There is one aspect of understanding running F# code that is crucial: debugging F# code. We have to be able to debug F# code, especially when we have very large projects that have hundreds of F# code files, not to mention when each of the code files may have too many lines of code. For example, having to check a running F# code that has more than 2,000 lines.

The following are the advantages of the debug features:

  • Isolating the error and focusing on it by inserting a breakpoint can ease the fixing of an error or bug. Developers are gaining more productivity because they can fix errors/bugs faster.

  • Debugging can also provide insightful information about the correctness of any value returning from a function.

  • Debugging can also be used to trace bugs further by examining the results from other referenced libraries as well. It is possible that we may use the referenced library incorrectly or the referenced library may also have bugs.

Visual F# in Visual Studio 2015 also has debugging capabilities. It was not as powerful when it was introduced in Visual Studio 2008 as additional add-on, but now the debugging experience is much better. It has been integrated with the Visual Studio extensibility model nicely, providing, for example, faster execution while running in the debug mode and having conditional breakpoints.

It is different from the C#/VB debugger because F#, although being a strongly and strictly typed language, currently has no support for evaluating expressions in the debugger's immediate windows in Visual Studio 2015.

Note

Some experienced F# developers may argue that this additional debug feature is not a big concern at all as F# has a tendency to enforce type restriction and correctness at the fabric of F# as a programming language. But for most other developers, especially those who jump from C#/VB to F#, the overall debugging experience is still lacking some features.

Currently these are the differences between the F# and C#/VB debugger in Visual Studio 2015:

Feature

F#

C#/VB

Breakpoint insertion

Yes.

Yes

Condition in breakpoint

Yes.

Yes

Intellisense in editing condition in breakpoint

Not supported because Intellisense is not yet linked to the whole infrastructure of the Visual Studio 2015 IDE extensibility and the F# compiler. There is a plan to have this feature for the next Visual Studio release after Visual Studio 2015.

Yes

Lightbulb assistant

Not available. There is a plan to have this feature for the next Visual Studio release after Visual Studio 2015, but the exact planned release is not quite clear.

Yes

Expression evaluation in immediate window

Not available.

Yes

Locals value

Yes.

Yes

Auto watch value

Yes.

Yes

Other than the features in the previous table, basic debugging with breakpoints in Visual F# is essentially the same as debugging in C#/VB.

Let's take some code to debug. To quickly have some code, we can use the F# 3.0 sample from CodePlex at:

http://fsharp3sample.codeplex.com/

After downloading the ZIP file of the code samples, unzip it to a folder and open the SampleProject.sln solution file in Visual Studio.

Note

You may read Readme.txt first before using the whole sample code. This readme guide is available in the Solution Item folder when opened in Solution Explorer.

Now, your screen should look like this:

Some of the samples in F# 3.0 are not valid anymore. You have to register for Azure DataMarket to access the F# Type Provider of Azure DataMarket.

There are some compiler errors if we try to rebuild the solution without changing the code at all, and one of the sample type providers, ESRI DataMarket, is not working.

Based on those invalid type provider conditions, to build this sample solution successfully, you have to follow these steps:

  1. Register with Azure DataMarket. You need to have your own Azure account key to access Azure DataMarket.

  2. The ESRI sample has not been working since 2014. Please comment the lines from line 135 to line 157 in the Samples.TypeProviders.AzureMarketPlace.fs file.

  3. Rebuild the solution. This will compile the whole solution and also resolve the type provider in the background for us to use.

  4. Now open the Samples.Beginners.fs file. Put the debugger breakpoints at lines 19 and 20 by clicking the line.

  5. To add breakpoints, you can simply toggle the highlighted column on the left before the line number like this:

  6. And we can also add breakpoints by right clicking and choosing Breakpoints.. and then Insert Breakpoint.

  7. Compile the code by initiating the Build Solution. Then press F5 to run. The window of F# Micro Sample Explore is displayed:

    This sample is actually a showcase of many F# features, from basic language constructs, units of measure, type providers, and LINQ, to concurrency such as async and parallelism.

  8. Now expand the Basic node on the left and choose Basic Data Types, and then choose the last node of Integer Arithmetic, as illustrated here:

  9. Going back to the source code of Samples.Beginner.fs, we can see that the node name is also the same as the name of the attributes in the code to categorize:

          [<Category("Basic Data Types"); 
            Title("Integer Arithmetic"); 
            Description("This sample shows some basic integer arithmetic")>] 
          let SampleArithmetic1() = 
              let x = 10 + 12 - 3  
              let y = x * 2 + 1  
              let r1,r2 = x/3, x%3 
              printfn "x = %d, y = %d, r1 = %d, r2 = %d" x y r1 r2 
    
  10. Click the Run Sample! button and Visual Studio will stop the execution at the breakpoint:

    Now we can debug our code easily. We can also look at the value of the variables or symbols that are currently in scope by checking the value at the Locals window.

  11. Press F10 to step over, and now we see the evaluated value of x and y:

Any local variables in Locals and watch expressions displayed in the Watch1 window always have the name, value, and type of the variables. The type displayed is using the F# keyword, not the full type name.

For example, int is displayed instead of System.Int32 as shown in Locals.

We can always check other values as well if we have another global or static global variable in the Watch1 window. The values can contain immediate values from an expression, for example DateTime.Now.

Unfortunately, we have to write using the full namespace of System.DateTime, so we have to write the expression as System.DateTime.Now:

This requirement to have the full namespace proves that debugger support in Visual F# still requires improvements compared to its C#/VB counterparts. Typing the full object name may be error prone, as F# watch does not support Intellisense yet.

After we have finished debugging and bug fixing, it is recommended to change the compilation to the Release mode. The Release mode will have a smaller compiled F# code and it executes faster because it does not contain debug symbols and any other debug information attached to the compiled code.

To change back and forth between Debug and Release is quite easy. We can simply change the mode at the drop-down menu in the Visual Studio toolbar:

There is no apparent distinction on the compiled DLL or EXE filename, other than the smaller size of the release mode.

To summarize, the following are the differences of the Debug mode and the Release mode:

Elements

Debug

Release

Debug symbol (PDB)

Included

Not included.

Size of compiled code

Bigger than the release mode, excluding the PDB file

Smaller than the debug mode.

Code optimization

Not optimized, as it is focused for debugging and it is also synchronized

Yes, but the code will not be able to be debugged easily, as the code is optimized for executions.

In .NET 4.6 and Windows 10, it is optimized further by compiling into native code using the Ahead Of Time (AOT) model instead of Just In Time (JIT).

Compilation symbol availability

DEBUG

Not applicable.

Execution

Slower than Release, as there is no optimization

Fast, since it is optimized for runtime, and there is no debug symbol overhead.

For more information about AOT and JIT, consult the MSDN Library at https://msdn.microsoft.com/en-us/library/dn807190(v=vs.110).aspx.