TheSharperDev

Educating about C# and F#

Seq.cache - F#

Lets examine Seq.cache.

Seq.cache: Returns a sequence that corresponds to a cached version of the input sequence. ~ FSharp.Core

Refreshing our memory of what a sequence is:

A sequence is a logical series of elements all of one type. Sequences are particularly useful when you have a large, ordered collection of data but do not necessarily expect to use all of the elements. Individual sequence elements are computed only as required, so a sequence can provide better performance than a list in situations in which not all the elements are used.

F# Guide

Sequences are different than lists, lists are a group of items, but sequences could require recomputation every time they’re invoked.

Because there’s recomputation, you could encounter performance problems, depending on what you’re recomputing.

Lets take a look at the docs example, a fibonacci sequence:

let fibSeq = 
    (0, 1) 
    |> Seq.unfold (fun (a,b) -> Some(a + b, (b, a + b)))

This definition of Fiboancci uses a sequence. Which means it isn’t the values of fibonacci, but a way to generate the values of fibonacci.

If I asked for the first 3 values of Fibonacci, this sequence would generate it. Everytime I called it would regenerate them.

If we leveraged Seq.cache, we could avoid that recomputation.

let fibSeq3 = 
    fibSeq 
    |> Seq.take 3 
    |> Seq.cache

[<EntryPoint>]
let main argv =
    let fib3 = fibSeq3

    printfn "%A" fib3
    0

Now the sequence of the first three fibonacci numbers are cached. And further generation of this sequence will avoid any costly performance problems.

Notes

  • If you’re trying to avoid recomputation for a general function (and not a sequence), try looking into memoization