相关疑难解决方法(0)

为什么使用序列比在此示例中使用列表慢得多

背景:我有一系列连续的,带时间戳的数据.数据序列中有孔,有些大,有些只有一个缺失值.
每当孔只是一个缺失值时,我想使用虚拟值修补孔(较大的孔将被忽略).

我想使用延迟生成修补序列,因此我使用Seq.unfold.

我已经制作了两个版本的方法来修补数据中的漏洞.

第一个消耗带有孔的数据序列并产生修补序列.这就是我想要的,但是当输入序列中的元素数量超过1000时,方法运行得非常慢,并且输入序列包含的元素越多,它就会越来越差.

第二种方法使用带有孔的数据列表并生成修补序列并且运行速度很快.然而,这不是我想要的,因为这会强制整个输入列表在内存中的实例化.

我想使用(sequence - > sequence)方法而不是(list - > sequence)方法,以避免在内存中同时存在整个输入列表.

问题:

1)为什么第一种方法如此缓慢(使用较大的输入列表逐渐变得更糟)(我怀疑它与使用Seq.skip 1重复创建新序列有关,但我不确定)

2)如何使用输入序列而不是输入列表快速修补数据中的空洞?

代码:

open System

// Method 1 (Slow)
let insertDummyValuesWhereASingleValueIsMissing1 (timeBetweenContiguousValues : TimeSpan) (values : seq<(DateTime * float)>) =
    let sizeOfHolesToPatch = timeBetweenContiguousValues.Add timeBetweenContiguousValues // Only insert dummy-values when the gap is twice the normal
    (None, values) |> Seq.unfold (fun (prevValue, restOfValues) ->  
        if restOfValues |> Seq.isEmpty then
            None // Reached the …
Run Code Online (Sandbox Code Playgroud)

performance f# yield lazy-evaluation seq.unfold

20
推荐指数
2
解决办法
4017
查看次数

F#基于相邻元素的比较将列表拆分为子列表

我在hubFS上发现了这个问题,但它根据各个元素处理分裂标准.我想根据相邻元素的比较进行拆分,因此类型如下所示:

val split = ('T -> 'T -> bool) -> 'T list -> 'T list list
Run Code Online (Sandbox Code Playgroud)

目前,我试图从Don的必要解决方案开始,但我无法弄清楚如何初始化和使用'prev'值进行比较.折叠更好的方式去?

//Don's solution for single criteria, copied from hubFS
let SequencesStartingWith n (s:seq<_>) =
    seq { use ie = s.GetEnumerator()
          let acc = new ResizeArray<_>()
          while ie.MoveNext() do
             let x = ie.Current
             if x = n && acc.Count > 0 then
                 yield ResizeArray.to_list acc
                 acc.Clear()
             acc.Add x
          if acc.Count > 0 then
              yield  ResizeArray.to_list acc }
Run Code Online (Sandbox Code Playgroud)

f# list

10
推荐指数
2
解决办法
2395
查看次数

基于谓词将列表拆分为列表列表

(我知道这个问题,但它与序列有关,这不是我的问题)

鉴于此输入(例如):

let testlist = 
    [  
       "*text1";
       "*text2";
       "text3";
       "text4";
       "*text5";
       "*text6";
       "*text7"
    ]

let pred (s:string) = s.StartsWith("*")
Run Code Online (Sandbox Code Playgroud)

我希望能够调用MyFunc pred testlist并获得此输出:

[
    ["*text1";"*text2"];
    ["*text5";"*text6";"*text7"]
]
Run Code Online (Sandbox Code Playgroud)

这是我目前的解决方案,但我真的不喜欢嵌套的List.revs(忽略它需要Seq作为输入的事实)

let shunt pred sq =
    let shunter (prevpick, acc) (pick, a) = 
        match pick, prevpick with
        | (true, true)  -> (true, (a :: (List.hd acc)) :: (List.tl acc))
        | (false, _)    -> (false, acc)
        | (true, _)     -> (true, [a] :: acc)

    sq 
        |> Seq.map (fun a -> (pred …
Run Code Online (Sandbox Code Playgroud)

f#

3
推荐指数
2
解决办法
2308
查看次数

标签 统计

f# ×3

lazy-evaluation ×1

list ×1

performance ×1

seq.unfold ×1

yield ×1