Skip to content

Commit 27f7443

Browse files
authored
Update conventions.md (#20287)
1 parent 095c08a commit 27f7443

1 file changed

Lines changed: 19 additions & 34 deletions

File tree

docs/fsharp/style-guide/conventions.md

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -102,34 +102,19 @@ open System.IO
102102
open System.Reflection
103103
open System.Text
104104
105-
open Microsoft.FSharp.Compiler
106-
open Microsoft.FSharp.Compiler.AbstractIL
107-
open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
108-
open Microsoft.FSharp.Compiler.AbstractIL.IL
109-
open Microsoft.FSharp.Compiler.AbstractIL.ILBinaryReader
110-
open Microsoft.FSharp.Compiler.AbstractIL.Internal
111-
open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
112-
113-
open Microsoft.FSharp.Compiler.AccessibilityLogic
114-
open Microsoft.FSharp.Compiler.Ast
115-
open Microsoft.FSharp.Compiler.CompileOps
116-
open Microsoft.FSharp.Compiler.CompileOptions
117-
open Microsoft.FSharp.Compiler.Driver
118-
open Microsoft.FSharp.Compiler.ErrorLogger
119-
open Microsoft.FSharp.Compiler.Infos
120-
open Microsoft.FSharp.Compiler.InfoReader
121-
open Microsoft.FSharp.Compiler.Lexhelp
122-
open Microsoft.FSharp.Compiler.Layout
123-
open Microsoft.FSharp.Compiler.Lib
124-
open Microsoft.FSharp.Compiler.NameResolution
125-
open Microsoft.FSharp.Compiler.PrettyNaming
126-
open Microsoft.FSharp.Compiler.Parser
127-
open Microsoft.FSharp.Compiler.Range
128-
open Microsoft.FSharp.Compiler.Tast
129-
open Microsoft.FSharp.Compiler.Tastops
130-
open Microsoft.FSharp.Compiler.TcGlobals
131-
open Microsoft.FSharp.Compiler.TypeChecker
132-
open Microsoft.FSharp.Compiler.SourceCodeServices.SymbolHelpers
105+
open FSharp.Compiler
106+
open FSharp.Compiler.AbstractIL
107+
open FSharp.Compiler.AbstractIL.Diagnostics
108+
open FSharp.Compiler.AbstractIL.IL
109+
open FSharp.Compiler.AbstractIL.ILBinaryReader
110+
open FSharp.Compiler.AbstractIL.Internal
111+
open FSharp.Compiler.AbstractIL.Internal.Library
112+
113+
open FSharp.Compiler.AccessibilityLogic
114+
open FSharp.Compiler.Ast
115+
open FSharp.Compiler.CompileOps
116+
open FSharp.Compiler.CompileOptions
117+
open FSharp.Compiler.Driver
133118
134119
open Internal.Utilities
135120
open Internal.Utilities.Collections
@@ -231,7 +216,7 @@ Use `nullArg`, `invalidArg` and `invalidOp` as the mechanism to throw `ArgumentN
231216

232217
The `failwith` and `failwithf` functions should generally be avoided because they raise the base `Exception` type, not a specific exception. As per the [Exception Design Guidelines](../../standard/design-guidelines/exceptions.md), you want to raise more specific exceptions when you can.
233218

234-
### Using exception-handling syntax
219+
### Use exception-handling syntax
235220

236221
F# supports exception patterns via the `try...with` syntax:
237222

@@ -437,18 +422,18 @@ Finally, automatic generalization is not always a boon for people who are new to
437422

438423
## Performance
439424

440-
### Prefer structs for small data types
425+
### Consider structs for small types with high allocation rates
441426

442427
Using structs (also called Value Types) can often result in higher performance for some code because it typically avoids allocating objects. However, structs are not always a "go faster" button: if the size of the data in a struct exceeds 16 bytes, copying the data can often result in more CPU time spend than using a reference type.
443428

444429
To determine if you should use a struct, consider the following conditions:
445430

446431
- If the size of your data is 16 bytes or smaller.
447-
- If you're likely to have many of these data types resident in memory in a running program.
432+
- If you're likely to have many instances of these types resident in memory in a running program.
448433

449434
If the first condition applies, you should generally use a struct. If both apply, you should almost always use a struct. There may be some cases where the previous conditions apply, but using a struct is no better or worse than using a reference type, but they are likely to be rare. It's important to always measure when making changes like this, though, and not operate on assumption or intuition.
450435

451-
#### Prefer struct tuples when grouping small value types
436+
#### Consider struct tuples when grouping small value types with high allocation rates
452437

453438
Consider the following two functions:
454439

@@ -480,7 +465,7 @@ When you benchmark these functions with a statistical benchmarking tool like [Be
480465

481466
However, these results won't always be the case in your own code. If you mark a function as `inline`, code that uses reference tuples may get some additional optimizations, or code that would allocate could simply be optimized away. You should always measure results whenever performance is concerned, and never operate based on assumption or intuition.
482467

483-
#### Prefer struct records when the data type is small
468+
#### Consider struct records when the type is small and has high allocation rates
484469

485470
The rule of thumb described earlier also holds for [F# record types](../language-reference/records.md). Consider the following data types and functions that process them:
486471

@@ -515,7 +500,7 @@ This is similar to the previous tuple code, but this time the example uses recor
515500

516501
When you benchmark these functions with a statistical benchmarking tool like [BenchmarkDotNet](https://benchmarkdotnet.org/), you'll find that `processStructPoint` runs nearly 60% faster and allocates nothing on the managed heap.
517502

518-
#### Prefer struct discriminated unions when the data type is small
503+
#### Consider struct discriminated unions when the data type is small with high allocation rates
519504

520505
The previous observations about performance with struct tuples and records also holds for [F# Discriminated Unions](../language-reference/discriminated-unions.md). Consider the following code:
521506

0 commit comments

Comments
 (0)