Suboptimal code generated when pattern matching a tuple in a lambda parameter
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 144
Description
When pattern matching a tuple in the parameter of a lambda function, the performance is inferior compared to using the `fst`/`snd` functions or pattern matching inside the function.
**Repro steps**
Consider the following example code:
```fsharp
let data = Map.ofList [
"1", (true, 1)
"2", (true, 2)
]
let foldWithPattern () =
(data, [])
||> Map.foldBack (fun _ (x, _) state -> x :: state)
let foldWithFst () =
(data, [])
||> Map.foldBack (fun _ v state -> fst v :: state)
let foldWithPattern2 () =
(data, [])
||> Map.foldBack (fun _ v state ->
let x, _ = v
x :: state)
```
I would expect the three functions to have similar performance and code-style-wise I would in many cases prefer the pattern match in the parameter.
[In the decomplied code](https://sharplab.io/#v2:DYLgZgzgPsCmAuACAJgQ3qxBeRBZVADgHQD2YAMgJYRIDaAsAFCIuIBEAjGwDSIAU8AE4BXWLw4BKJq3YAmHvyGjesqYwC6TJnCRgSwZAHVK8ABYAFdPFiCAdvwnZprPmgy9a6tTKhQAfHiERHoGAEKoAMYA1vxgwvYA+vwAHrwJjjTosIgAtAHJiCAgiJnWatoIiCFGJqYAYjQOTswubqgeXs4svgH4xNXh0bHxiEkAbiUY1rkBkEgTRZNZ3qwVuvo1Zpbw1nayTVhd/G0dK93+gf0bgzF8cYmIE6XZeUcyOoipo9iPb6wFi2eEiAA=), two FSharpFunc classes are created when the pattern matching in the parameter is used.
Benchmark result with the example code:
```
BenchmarkDotNet v0.13.8, Windows 10 (10.0.19045.3448/22H2/2022Update)
AMD Ryzen 7 1700, 1 CPU, 16 logical and 8 physical cores
.NET SDK 7.0.401
[Host] : .NET 7.0.11 (7.0.1123.42427), X64 RyuJIT AVX2 DEBUG
DefaultJob : .NET 7.0.11 (7.0.1123.42427), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio |
|---------------- |---------:|---------:|---------:|------:|-------:|----------:|------------:|
| FoldWithPattern | 58.40 ns | 1.113 ns | 1.041 ns | 1.00 | 0.0324 | 136 B | 1.00 |
| FoldWithFst | 39.90 ns | 0.483 ns | 0.452 ns | 0.68 | 0.0153 | 64 B | 0.47 |
```
**Expected behavior**
Pattern matching a tuple in a parameter does not affect performance.
**Actual behavior**
Pattern matching a tuple in a parameter degrades performance and causes more memory allocations.
**Known workarounds**
Use the `fst`/`snd` functions or do the pattern match in the body of the lambda function.
Contributor guide
Assessment
This issue has not been assessed yet.