Search code examples
performancef#functional-programminginlinepipeline

Performance implications of ||> and |||> pipeline operators in F#


This question basically expands on this question where the answer is that the single argument pipeline operator |> is compiled to the same CIL as the unpiped version. But what about ||> and |||>? MSDN suggests that real tuples are used to wrap the arguments.

But do ||> and |||> really allocate a .NET Tuple to wrap the arguments and then unwrap them again just pass them to a function or is the compiler optimized to handle these operators by just rewriting the CIL like it does with |>?

Update:

Thank you for the answers. It depends on whether the --optimize+ parameter is passed to the F# compiler.

Default release builds in with F# 3.1 in Visual Studio 2013 don't create tuples. Default debug builds do create tuples.


Solution

  • Yes, where possible, the compiler will optimize away the operators just like it does with |>.

    Just as a fun example, the compiler will optimize this code

    let add a b = a + b
    let test() = (1,2) ||> add
    

    to this

    3
    

    And even if you parameterised test

    let test t = t ||> add
    

    it would compile to this C# equivalent

    int test(int x, int y) { return x + y; }
    

    In real, more complex code, you might not see such extreme optimizations but it gives you an idea of what the compiler can do.