F# High Performance - Eriawan Kusumawardhono - E-Book

F# High Performance E-Book

Eriawan Kusumawardhono

0,0
38,39 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Build powerful and fast applications with F#

About This Book

  • Explore the advanced concurrency support in F# and .NET TPL
  • Covers major optimization techniques in F# to improve the performance of applications
  • Use Struct, Class and Record model, Interop with C# and VB without sacrificing performance.

Who This Book Is For

This book is for F# developers who want to build high-performance applications. Knowledge of functional programming would be helpful.

What You Will Learn

  • Understand how the execution of functions in F# works
  • Identify common performance bottlenecks
  • Implement best practices to optimize performance
  • Use the available tooling to help measure performance
  • Combine the best practice of asynchronous and synchronous
  • Optimize further using various F# language constructs

In Detail

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.

Style and approach

This easy-to-follow guide is full of hands-on examples of real-world multithreading tasks. Each topic is explained and placed in context, and for the more inquisitive, there are also more in-depth details of the concepts used.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 424

Veröffentlichungsjahr: 2017

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Table of Contents

F# High Performance
Credits
About the Author
About the Reviewer
www.PacktPub.com
Why subscribe?
Customer Feedback
Preface
What this book covers 
Who this book is for 
What you need for this book 
Basic requirements and setup environments
Conventions 
Reader feedback
Customer support
Downloading the example code
Errata
Piracy
Questions
1. Performing Common Optimizations in F#
Understanding the nature of F# code
F# runtime characteristics
Relation between F# code and its generated assembly
Immutability versus mutability
Overview of common bottlenecks
Common samples of misunderstood concurrent problems
Introduction to concurrency in F#
Defining asynchronous
Misunderstood concurrency problems
Introduction to concurrency support in .NET and F#
Overview of F# tooling in Visual Studio
Interactive support for F# interactive
Introduction to debugging in F#
Summary
2. Performance Measurement
Introduction to the nature of F# code compilation
General overview of F# compiler processes and results
A quick overview of IL in F#
IL tooling in .NET
Using ILDASM and ILASM to understand low-level IL assembly
Using CLR Profiler 4.5
A quick overview of CLR Profiler
A quick walkthrough of CLR Profiler in action
Ways to measure performance quantitatively
Using .NET timers
Running functions inside unit tests
A quick introduction to unit tests
Unit test support in Visual Studio
Using FsUnit to implement a unit test in F#
Summary
3. Optimizing Data Structures
Overview and best practices of types in F#
Static typing versus dynamic typing
Quick introduction to types in F#
Quick overview of generic type support in F#
Overall runtime strategy of handling data types
Introduction to memory storage allocation
Register
Stack
Heap
Best practices of types for storing and accessing data
Best practices in using F# collections
Comparing F# List to .NET List<T>
Comparing F# Map to Dictionary<TKey,TValue>
Choosing a value evaluation strategy
Scenarios involving evaluation strategy and memory allocations
Summary
4. Introduction to Concurrency in F#
Introducing concurrency support in F# 4
Identifying blocking threads
Overview of the background technical reasons for the blocking nature of I/O
Obvious trait of a blocking thread
Introducing asynchronous workflow
Getting to know asynchronous workflow
Using asynchronous with Dispose pattern
Operations in asynchronous workflow
Creating child asynchronous workflow
F# asynchronous workflow support for legacy .NET APM and EAP
Ignoring asynchronous operation asynchronously
Delaying asynchronous workflow
Handling cancellation in asynchronous workflow
Common conventions when implementing asynchronous operations
Introduction to interop with .NET TPL
A quick overview of asynchronous programming in .NET TPL
Summary
5. Advanced Concurrency Support in F#
Using F# MailboxProcessor
Background case of having message agent
Introducing fire and forget pattern
Overview of a message agent
Overview of serialization
Introduction to F# MailboxProcessor
Overview of MailboxProcesor features
Further implementations of MailboxProcessor
Managing side effects inside MailboxProcessor and asynchronous workflows
Parallel programming with .NET TPL
Overview of task-based parallelism
Quick start-using the parallel debugging tool in Visual Studio
Overview of data parallelism
Common potential pitfalls in parallel programming
Overview of handling mutable state
Summary
6. Optimizing Type Provider
Overview of F# type provider
Comparing the type provider with other type generators
Interoperability with other managed programming languages
Understanding the type provider building blocks
Minimum requirements of type providers
Strategies of type provider implementation
Choosing strategies of type provider implementation
Sample usage of built-in type provider in F#
Quick sample of using SqlDataConnection type provider
Implementing your own type provider
Building the type's building blocks
Building type metadata infrastructure
Implementing assembly to provide base assembly
Implementing parameters for methods and constructors
Implementing generated constructor
Implementing generated methods
Implementing generated properties
Basic minimal implementation of type provider
Common pitfalls in implementing type provider
Summary
7. Language Features and Constructs Optimization
Overview of language features and constructs optimization
Optimizing common F# language constructs
Best practices of interoperability of F# delegate with .NET delegate
Passing a .NET delegate as an F# function
Calling .NET delegate within F#
Best practices in pattern matching and active pattern
Comparing constant pattern matching with if constructs
Best practices in using active patterns
Considerations in catching exceptions in active patterns
Optimizing inline functions
Background overview of inline functions and related type inferences
Overview of F# type inference mechanism of generic type inference
Overview of automatic generalization in F#
Best practices in implementing inline functions
Identifying tail call in recursive constructs
Overview of recursion in functional programming
Tail call recursion in F# and .NET CLR
Identifying tail call optimized implementation
Advantages of having tail call recursive implementation
Limitations of tail call recursion in F#
Summary
8. Optimizing Computation Expressions
Quick introduction to F# computation expression
Introduction to builders of computation expression
Using F# function/delegate over .NET Func
Relation of F# function computation expressions with arguments restriction
Walkthrough of planning and writing a computation expression
Understanding the use of type returned in computation expression
General computation expression design considerations
Implications of the design considerations of computation expression
Considerations of computation expression optimization
Summary

F# High Performance

F# High Performance

Copyright © 2017 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

First published: January 2017

Production reference: 1130117

Published by Packt Publishing Ltd.

Livery Place

35 Livery Street

Birmingham B3 2PB, UK.

ISBN 978-1-78646-807-9

www.packtpub.com

Credits

Author

Eriawan Kusumawardhono

Copy Editor

Safis Editing

Reviewer

Arthur Pham

Project Coordinator

Ulhas Kambli

Commissioning Editor

Kunal Parikh

Proofreader

Safis Editing

Acquisition Editor

Sonali Vernekar

Indexer

Tejal Daruwale Soni

Content Development Editor

Nikhil Borkar

Graphics

Abhinash Sahu

Technical Editor

Hussain Kanchwala

Production Coordinator

Shraddha Falebhai

About the Author

Eriawan Kusumawardhono is a veteran senior software development engineer (SDE) who has software development experience of more than 13 years, with 11 years of having developed in .NET, since the introduction of Visual Studio 2003. On usual working day he works at Allegro Development, a software development company, and in his spare time, he does speaking and training for software development and programming language communities in Indonesia. He is also a member of F# Foundation speaker program. He enjoys being a full-time technical polyglot software developer, mingling both OOP and functional programming at the same time.

He currently holds a Microsoft MVP award in Visual Studio development platform competency, from 2011 to 2017, for more than 5 consecutive years.

He lives in Jakarta with his wife, enjoying reading and cooking heterogeneous exotic food in Indonesia.

Many thanks to Microsoft, especially Microsoft Research, and Don Syme for developing F#, a functional programming that meets OOP nicely and truly pragmatic! I would like to give special thanks to Packt for giving me the chance to write this wonderful book and Nikhil for his continuous support and always giving me constructive feedback. I also would like to give a big huge thanks for my lovely wife, Dini Kusumawardhono, for always giving me unconditional love and support during the writing of this book and also her continuous understanding every day. I would like to dedicate this book to software development communities in Indonesia, and to all of the F# developer communities around the world. F# rocks!

About the Reviewer

Arthur Pham has been working for Thomson Reuters as a Lead Quantitative Engineer since 2006.

He has spent many years designing and implementing derivatives pricing models and still loves learning new programming languages, such as F#, C++, Python, Flex/ActionScript, C#, Ruby, and JavaScript.

He currently lives in New York, NY, USA and can be contacted on Twitter at @arthurpham.

www.PacktPub.com

For support files and downloads related to your book, please visit www.PacktPub.com.

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.

https://www.packtpub.com/mapt

Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.

Why subscribe?

Fully searchable across every book published by PacktCopy and paste, print, and bookmark contentOn demand and accessible via a web browser

Customer Feedback

Thank you for purchasing this Packt book. We take our commitment to improving our content and products to meet your needs seriously—that's why your feedback is so valuable. Whatever your feelings about your purchase, please consider leaving a review on this book's Amazon page. Not only will this help us, more importantly it will also help others in the community to make an informed decision about the resources that they invest in to learn. You can also review for us on a regular basis by joining our reviewers' club. If you're interested in joining, or would like to learn more about the benefits we offer, please contact us: [email protected].

Preface

It’s well-known today that F# has been quite a first class citizen, a built-in part of programming language support in Visual Studio from Visual Studio 2010. F# is a programming language that has its own unique trait: it is a functional programming language, and at the same time, it has OOP support. F# has run on .NET until now, although we can also run F# as a cross-platform language, such as on Android (using Mono).

Although F# mostly runs faster than C# or VB when doing computations, F# has its own unique performance characteristics. Some of the performance characteristics might not be so obviously identified and code implementations might have implicit bad practices and subtleties that may lead to performance bottlenecks. The bottlenecks may or may not be faster than C#/VB counterparts, although some of the bottlenecks may share the same performance characteristics, such as the use of .NET APIs.

The main goal of this book is to identify the performance problems in F#, measuring and optimizing F# code to run more efficiently, while also maintaining the functional programming style as appropriately as possible.

This book focuses on optimizing F#. A basic skill of F# knowledge (including functional programming concept and basic OOP) is a prerequisite to start understanding its performance problems and optimizing F#.

What this book covers 

Chapter 1, Performing Common Optimizations in F#, introduces F# and gives an overview of the common problems in F# code.

Chapter 2, Performance Measurement, helps you get to know what and how to measure and the tooling ecosystem to measure performance.

Chapter 3, Optimizing Data Structures, helps you decide the best and the most optimal use of F#-specific data structures and optimize them.

Chapter 4, Introduction to Concurrency in F#, provides a general introduction to the concept of concurrency and concurrency implementation support in F#.

Chapter 5, Advanced Concurrency Support in F#, provides best practices in implementing advanced concurrency support in F#, including interop with .NET TPL and avoiding performance pitfalls.

Chapter 6, Optimizing Type Provider, gives a quick walk-through of type provider implementation, while at the same time providing optimization and avoiding performance pitfalls in implementing your own custom type providers.

Chapter 7, Language Features and Constructs Optimization, explains best practices when implementing and using various F# language features and constructs without sacrificing the performance and correctness in functional programming.

Chapter 8, Optimizing Computation Expressions, explains best practices in using F# computation workflows and optimizing your own implementation of a computation workflow.

Who this book is for 

This book is for F# developers who want to build high-performance applications. Knowledge of functional programming would be helpful.

What you need for this book 

We need to ensure that we have met all of the software and hardware requirements and that we have their correct versions as well.

Basic requirements and setup environments

The following are the requirement specifications for an F# environment:

Visual Studio 2015 Update 3. The minimum edition is Community Edition because it is the free minimum version of Visual Studio, which has extensibility support and Visual F# (also F# project templates) as part of the installation. Express Edition is not recommended because it has no F# project templates built in..NET 4.6 as the minimum target runtime.Windows 7 SP1 (Windows 8.1 Update 1 64-bit or Windows 10 64-bit is recommended)

The following are the Visual Studio 2015 Update 3 hardware requirements:

4 GB RAM on Windows 7 SP1 or 6 GB RAM on Windows 8.1 and Windows 10.At least a Core 2 Duo or Athlon processor. It is recommended to have Core i5 as it is also a recommendation for a Windows 8.1 or Windows 10 machine. Also, using Core i5 will provide easier illustrations to see multi core in action when we discuss concurrency in Chapter 4 and 5.Approximately 12 GB to 15 GB of disk space with Windows 10 UWP installed (without Android development feature).DirectX 9.0c capable display adapter.

For more information, please check the requirement specification on MSDN:

https://www.visualstudio.com/en-us/downloads/visual-studio-2015-system-requirements-vs.aspx

Note

We recommend having at least 8 GB of RAM. This minimal memory size is recommended in order to have an optimal experience for not just running F# code. For large F# projects, Visual Studio IDE will load type information, metadata and debug symbols in the background, and Visual Studio's memory consumption will quickly climb to more than 3 GB. This is why 64-bit Windows is recommended as it allows us to use RAM higher than 4 GB.  

Reader feedback

Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of.

To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message.

If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.

Customer support

Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.

Downloading the example code

You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

You can download the code files by following these steps:

Log in or register to our website using your e-mail address and password.Hover the mouse pointer on the SUPPORT tab at the top.Click on Code Downloads & Errata.Enter the name of the book in the Search box.Select the book for which you're looking to download the code files.Choose from the drop-down menu where you purchased this book from.Click on Code Download.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR / 7-Zip for WindowsZipeg / iZip / UnRarX for Mac7-Zip / PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/F-Sharp-High-Performance/ We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Errata

Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.

To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.

Piracy

Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.

Please contact us at [email protected] with a link to the suspected pirated material.

We appreciate your help in protecting our authors and our ability to bring you valuable content.

Questions

If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.

Overview of common bottlenecks

F# has common bottlenecks although they might be subtle as well.

In order to be able to quickly understand the bottleneck factors in F#, we will categorize the shared general bottlenecks of .NET as managed bottlenecks (also in C#/VB), and F#-only bottlenecks (this includes when using F# with other languages).

The following are managed .NET bottlenecks (from obvious to less obvious):

String concatenations, such as using string String.Concat instead of StringBuilder. This is often overlooked because of a lack of awareness of the string's immutability.Usage of non-generic collections such as ArrayList.Incorrectly handling side effects, such as exceptions and I/O.Mutable objects usage, including casting.Complex objects that will be serialized and deserialized, for example: sending DataSet that has DataTables over HTTP.Ignoring performance profiling.

Side effects mean all of the elements outside the formal computation (it is often called the outside world) that we interact with, and this includes the changing global state. The outside world can be all of the things that we cannot fully determine as the end result. Examples of the outside world include:

I/O: This is included as being part of the outside world because you cannot determine or guarantee any kind of work you pass to I/O to be successfully completed. For example, when sending a command to a printer to print a document, we cannot guarantee 100% success of the printing operation. We cannot even guarantee that the process of sending the data to the printer will be successful or not before the printer receives the data and begins to print the document.Global static mutable variables: A quick example of this is when we define a public static variable in the scope of ASP.NET. Every value change will always change the condition of any user of the ASP.NET application.Functions or properties that always have different results when they are invoked, such as DateTime.Now.

Note

DateTime.Now will always return different results and this is as expected because the result must change every time it is called or instantiated. It is not free of side effects, but it is still expected to always return a different result.

Side effects are not just for functional programming developers, as many of us are now becoming quite aware. There are no absolute side effect-free computations because we should learn and be able to correctly handle them. For example, even printing a screen to a console is also a side effect because it involves I/O, and it changes the state of the outside world.

The following are F#'s unique bottlenecks:

Incorrect use of data structures and collectionsIncorrect use of auto generalization and other language constructsIncorrectly implemented concurrency problems, such as mixing synchronous and asynchronous although the original intention is asynchronousSlow performance when having to interoperate with other languages' class libraries such as C#/VBScaling MailboxProcessor in F#Identifying when tail call optimization should occurSlow response when resolving type in type provider implementationSlow performance when implementing computation workflow

Common samples of misunderstood concurrent problems

Many of us, when dealing with concurrent problems, sometimes try to use a hammer for every nail. There is no silver bullet for all of the problems of implementing concurrency.

It is also recommended to understand concurrency, as concurrency is now becoming more relevant because of the many core models in the releases of modern microprocessors (or simply processors) in the last 7 years. This fact is also becoming a trend as the clock speed of the latest processors has been usually limited to 3.2 GHz for the last 3 years.

Microsoft's Visual C++ architect, Herb Sutter, has written a very thorough article in the form of a whitepaper famously known as The Free Lunch Is Over: 

http://www.gotw.ca/publications/concurrency-ddj.htm

Let's understand first what concurrency is and the F# supports.

Introduction to concurrency in F#

Before we dive deeper into concurrency in F#, we should understand the definition of concurrency.

Concurrency is one of the main disciplines of computer science and it is still one of the main problems of computations.

Simply defined, concurrency is the composition of the order of independent process units or partially-ordered process units that can be executed in parallel or not in parallel, but not in sequential order. The term order in this context means ordered as sequentially.

The following diagram illustrates the concept of sequential (not concurrent) in action:

Process 1 to Process 4 as shown in the preceding diagram is executed sequentially step by step. Process 2 must wait for Process 1 to be completed first, as do Process 3 and Process 4.

This sequence is also called a synchronous process or is simply referred to as being synchronous.

The following figure is a sample illustration of a parallel concurrency combination of parallel and synchronous processes:

Processes 1A, 2A, and 3A run in parallel, although each parallel lane has its own sequence of processes that are run sequentially.

The term parallel means that it is not just executing simultaneously in parallel, but parallel also means that it may run on many processors or on many cores, as is common in modern processors that have multiple cores.

Defining asynchronous

A simple definition of asynchronous means not synchronous. This means that if we have an asynchronous flow, the process is not run synchronously.

These are the implications of an asynchronous flow:

Processes run not sequentially. For example, if the first process is running asynchronously, the next process doesn't have to wait for the first process to be completed.There has to be a way of scheduling and telling the scheduler to inform that the asynchronous process is completed. Typically, the asynchronous process is usually related to blocking I/O or some long computations.At first, the processes may look sequential, but the next process run may not be sequential at all.

This is a sample case of asynchronous: a customer is going to have dinner in a restaurant. The flows are:

Customer A orders some food or drinks, and the order is noted by waiter X. Usually, most restaurants have more than one waiter, but for this illustration, the waiter available currently to serve customer A is waiter X.Waiter X then gives the list of the customer's order to chef Y.Chef Y accepts the order, and checks if he is currently occupied or not. If he is occupied, the order is registered as part of his cooking queue. Otherwise, he will start to cook the order.The waiter does not have to wait for the chef to complete his cooking. He can then serve other customers who have just arrived or there might be customers that want to add more food or drinks as well.Chef Y finishes his cooking for customer A, and then gives a notification to waiter X to inform that his cooking for customer A is finished. Or he can inform all waiters to tell that the cooking for customer A is finished. This concept of informing to tell a process is finished is commonly called a callback.Waiter X (or any other waiter) delivers the finished food to customer A.

The asynchronous model that uses a notification to inform that a process is completed is called asynchronous callback.

The result returned at the end of the execution later (or in the future) is called a Future. It is also the future, in a sense, when many processes are executed in parallel, having results later.

This is the official documentation of Future in MSDN Library: 

https://msdn.microsoft.com/en-us/library/ff963556.aspx

For I/O operations, such as printing a document, we cannot determine whether the printing is successful or not, so the notification of the end process is not available. We can implement an asynchronous operation on I/O, and the fact that there is no observable notification of this is why this asynchronous model is called the asynchronous fire and forget model.

Misunderstood concurrency problems

Many developers, even seasoned or experienced developers, still think that concurrency and parallel programming are different. Actually, parallel programming is just one member within the concurrency discipline, together with the differentiation of asynchronous and synchronous processing models.

This is also one of the most misunderstood concurrency concepts or problems, and there are many more regarding how we approach concurrency.

These are some common organized sample cases of misunderstood concurrency problems:

Assuming all concurrent problems can be solved using parallel programming.

Fact: Not all concurrent problems are easily solved with parallelism.

Assuming all implementation of asynchronous is asynchronous.

Fact: This depends on how we implement async; sometimes the execution of an async construct is executed synchronously.

Ignoring blocking threads such as I/O.

Fact: Blocking I/O threads should be handled asynchronously; otherwise, the current thread is always waiting indefinitely until the I/O thread is finished.

The synchronized lock is blocking.

Fact: The lock is not a blocking thread.

Relying on the CPU speed.

Fact: The CPU speed increase is becoming less of an issue. The research and development of modern CPUs is focusing on multiple core CPUs.

A few sample cases of concurrent problems are mentioned as follows:

The case samples of the first case are:

Ordering or sorting a collection: Ordering is by default a sequential process, and it requires iterating all the elements of the collection. Therefore, it's useless to use parallelism.Grouping data: Grouping data is implicitly one of the sequential processes; it is also quite useless to use parallelism.Printing reports: Printing is part of I/O and I/O is intrinsically without support for parallelism. Unless the I/O is part of I/O parallelism, it is useless to use parallelism in this context.

Sample cases of the second case are listed as follows:

Mixing Parallel.For that has F# async in it. The implications of having Parallel.For is by default taking a multiple core or a CPU to run it is not the same as running asynchronously, as it is not guaranteed to run as a combined async in parallel.Using Thread.Sleep instead of Async.Sleep to signify a wait operation. The call to Thread.Sleep will instead make the flow synchronous, as the Sleep method simply puts on hold the current thread as a delay synchronously.

Note

RAID array in the storage I/O is one of the best samples of parallelism in I/O. It stores data in parallel across multiple disks. It is faster than common I/O because data is stored in parts (not whole data to a disk) to several disks in parallel.

The third case is related to all of the I/O operations including sending data to a printer and saving large data into a disk. These operations are always blocking threads.

For the case of lock, Microsoft has issued official statements that lock in .NET used by C# and VB is executed without any interruption, and it only locks an object until it has finished executing the block in the synchronized lock. It's still allowing other threads to run without waiting for the thread that has the lock to finish.

This is the official thread synchronization of C# and VB in MSDN: 

https://msdn.microsoft.com/en-us/library/ms173179.aspx

It is recommended to always check online the MSDN Library of the .NET class library, as this is always updated.

Introduction to concurrency support in .NET and F#

Concurrency support in F# is based on the existing work of concurrency support features in .NET BCL (the Base Class Library). It's also by design, since F# runs on top of .NET CLR and can use .NET BCL. F# also has its unique ways that bring more features other than just language features (for example, asynchronous computations).

The .NET BCL part of concurrency has basic support for the following:

ThreadLockMutex

Beginning with .NET 4.0, we have the Task Parallel Library (TPL). This library makes concurrent support easier. TPL consists of the following:

Data parallelism (for example: Parallel.For and ForEach)Task parallelismAsynchronous task (this is also the base foundation of C#/VB's async-await)Parallel LINQ (often abbreviated as PLINQ)

For a more complete reference of concurrency support in .NET, please visit https://msdn.microsoft.com/en-us/library/hh156548(v=vs.110).aspx.

Note

.NET has no support yet for fiber API in Win32 API. Microsoft currently has no definite plan for fiber support.

F# has its own unique features of concurrency supports. They are:

Asynchronous workflow or computationMailboxProcessorParallel asyncParallel async combined with I/O

More on concurrency support in F# is available in Chapter 4, Introduction to Concurrency in F# and Chapter 5, Advanced Concurrency Support in F#.

Now it's time to dive more into some codes. To start writing F# code, we can use F# and Visual Studio combined. This includes IDE supports for F#.

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