首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个F#序列表达式是立方时间而不是线性时间?

为什么这个F#序列表达式是立方时间而不是线性时间?
EN

Stack Overflow用户
提问于 2020-02-10 08:18:22
回答 1查看 320关注 0票数 1

我在使用Seq.unfold时偶然发现了一种奇怪的时间复杂性行为。这是我能想出的最起码的例子来重现这个。

代码语言:javascript
复制
let idUnfolder sequence =
   sequence
   |> Seq.tryHead
   |> Option.map (fun head -> (head, Seq.tail sequence))

let seqIdWithUnfold sequence =
   Seq.unfold idUnfolder sequence

函数seqIdWithUnfold返回给定序列本身。如果Seq.unfold为O(n),Seq.tryHeadSeq.tail为O(1) (如果我错了,请纠正我的错误),我希望结果序列在线性时间内被迭代。然而,据我所知,它有一个立方的复杂性。

我使用以下函数使用一组n值测试了执行时间。

代码语言:javascript
复制
let test n =
   let start = System.DateTime.Now
   Seq.init n id
   |> seqIdWithUnfold
   |> Seq.iter ignore
   let duration = System.DateTime.Now - start
   printfn "%f" duration.TotalSeconds

是什么使这个操作变得复杂?

EN

回答 1

Stack Overflow用户

发布于 2020-02-18 03:26:13

正如Philip在评论中提到的,Seq.tail是O(n)。

我不知道为什么F#列表是不可接受的,F#列表是单链接列表,所以您可以得到固定的时间尾。如果您需要接受任何序列,因为您的签名只是在展开之前转换成一个列表,它仍然使它成为O(n),除非您真的不需要尾巴,否则这个示例无论如何也不能懒惰。

代码语言:javascript
复制
let seqIdWithUnfold sequence =
       sequence
           |> Seq.toList
           |> List.unfold idUnfolder 
           |> List.toSeq

您的处理示例仍然适用于列表模块。

代码语言:javascript
复制
 let idUnfolder listSeq =
        listSeq
        |> List.tryHead
        |> Option.map (fun head -> (head, List.tail listSeq))

但我觉得它看起来会更干净些

代码语言:javascript
复制
let idUnfolder =
    function | [] -> None
             | h::t -> Some(h, t);

本章

代码语言:javascript
复制
|          Method |        Mean |     Error |    StdDev |
|---------------- |------------:|----------:|----------:|
|        Original | 4,683.88 us | 36.462 us | 34.106 us |
|  ListConversion |    15.63 us |  0.202 us |  0.179 us |

// * Hints *
Outliers
  Benchmarkem.ListConversion: Default -> 1 outlier  was  removed (16.53 us)

// * Legends *
  Mean   : Arithmetic mean of all measurements
  Error  : Half of 99.9% confidence interval
  StdDev : Standard deviation of all measurements
  1 us   : 1 Microsecond (0.000001 sec)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60146456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档