F# (Mis)理解Seq.cache

F# (Mis)理解Seq.cache,f#,sequence,F#,Sequence,我有以下代码(在一个更大的函数中,但这不重要): let ordersForTask=Dictionary() 让getOrdersForTask任务= 将ordersForTask.TryGetValue任务与 |正确,订单->订单 |错误,-> 发号施令= 场景。订单 |>Seq.filter(fun(order:order)->order.Tasks.Contains(task)) |>Seq.cache ordersForTask.Add(任务、订单) 命令 据我所知,这应该会导致对每

我有以下代码(在一个更大的函数中,但这不重要):

let ordersForTask=Dictionary()
让getOrdersForTask任务=
将ordersForTask.TryGetValue任务与
|正确,订单->订单
|错误,->
发号施令=
场景。订单
|>Seq.filter(fun(order:order)->order.Tasks.Contains(task))
|>Seq.cache
ordersForTask.Add(任务、订单)
命令
据我所知,这应该会导致对每对
order
task
值调用
order.Tasks.Contains()
一次,无论使用相同的
task
值调用
getOrdersForTask
的频率有多高,因为输入序列只迭代(最多)一次。然而,情况似乎并非如此;如果我为我拥有的
task
的所有值调用函数
n
次,则分析显示
n*订单数量*任务数量
调用
Contains()

Seq.toList
替换
Seq.cache
具有我预期的效果,但我希望避免产生
Seq.toList
的成本


我对
Seq.cache
有什么误解,或者它的用法有什么错误?

看起来每次调用函数时,函数都会返回一个新的缓存序列。也许这对你会有帮助:
task
是上游C#code中某个地方定义的一个普通CLR类。为了确保我用
task=int
orders=int-seq
和一个简单的过滤函数(
n->n%5==0
)尝试了你的构造(包括查看调用的跟踪消息)-在F#interactive中,它可以正常工作(意思是:过滤函数只有在我第一次使用某个数字求值时才会被调用)-您能否尝试给出一个最小的示例来说明您的问题,这样我们就可以看到一个失败的版本?仅供参考;这可能有助于研究(第1385行)。请注意,使用Seq.cache也有成本(最显著的是锁)。有时候Seq.toArray可能更有效。下面是一个独立的复制尝试,与@CarstenKönig的评论类似。很好。我们需要完整的示例代码。
let ordersForTask = Dictionary<_, _>()

let getOrdersForTask task =
    match ordersForTask.TryGetValue task with
    | true, orders -> orders
    | false, _ ->
        let orders =
            scenario.Orders
            |> Seq.filter (fun (order : Order) -> order.Tasks.Contains(task))
            |> Seq.cache

        ordersForTask.Add(task, orders)
        orders