Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suboptimal code generated when pattern matching a tuple in a lambda parameter #16037

Open
iminashi opened this issue Sep 24, 2023 · 0 comments
Open
Labels
Milestone

Comments

@iminashi
Copy link

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:

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, 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: New
Development

No branches or pull requests

3 participants