- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有一个众所周知的解决方案可以生成无限的汉明数流(即所有正整数 n
其中 n = 2^i * 3^j * 5^k
)。我在 F# 中以两种不同的方式实现了这一点。第一种方法使用 seq<int>
.解决方案很优雅,但性能很糟糕。第二种方法使用自定义类型,其中尾部包裹在 Lazy<LazyList<int>>
中。 .该解决方案笨拙,但性能惊人。
有人可以解释为什么使用 seq<int>
的性能是如此糟糕,如果有办法解决它?谢谢。
方法 1 使用 seq<int>
.
// 2-way merge with deduplication
let rec (-|-) (xs: seq<int>) (ys: seq<int>) =
let x = Seq.head xs
let y = Seq.head ys
let xstl = Seq.skip 1 xs
let ystl = Seq.skip 1 ys
if x < y then seq { yield x; yield! xstl -|- ys }
elif x > y then seq { yield y; yield! xs -|- ystl }
else seq { yield x; yield! xstl -|- ystl }
let rec hamming: seq<int> = seq {
yield 1
let xs = Seq.map ((*) 2) hamming
let ys = Seq.map ((*) 3) hamming
let zs = Seq.map ((*) 5) hamming
yield! xs -|- ys -|- zs
}
[<EntryPoint>]
let main argv =
Seq.iter (printf "%d, ") <| Seq.take 100 hamming
0
Lazy<LazyList<int>>
.
type LazyList<'a> = Cons of 'a * Lazy<LazyList<'a>>
// Map `f` over an infinite lazy list
let rec inf_map f (Cons(x, g)) = Cons(f x, lazy(inf_map f (g.Force())))
// 2-way merge with deduplication
let rec (-|-) (Cons(x, f) as xs) (Cons(y, g) as ys) =
if x < y then Cons(x, lazy(f.Force() -|- ys))
elif x > y then Cons(y, lazy(xs -|- g.Force()))
else Cons(x, lazy(f.Force() -|- g.Force()))
let rec hamming =
Cons(1, lazy(let xs = inf_map ((*) 2) hamming
let ys = inf_map ((*) 3) hamming
let zs = inf_map ((*) 5) hamming
xs -|- ys -|- zs))
[<EntryPoint>]
let main args =
let a = ref hamming
let i = ref 0
while !i < 100 do
match !a with
| Cons (x, f) ->
printf "%d, " x
a := f.Force()
i := !i + 1
0
最佳答案
Ganesh 是对的,因为您正在多次评估序列。 Seq.cache
将有助于提高性能,但您可以从 LazyList
中获得更好的性能因为底层序列只会被评估一次然后被缓存,所以它可以被更快地遍历。事实上,这是一个很好的例子,其中 LazyList
应该在正常情况下使用 seq
.
看起来您使用 Seq.map
会带来一些显着的开销。这里。我相信编译器每次在那里被调用时都会分配一个闭包。我换了你的seq
使用的基础代码 seq
-expressions 代替,它比序列中的前 40 个数字的原始速度快约 1/3:
let rec hamming: seq<int> = seq {
yield 1
let xs = seq { for x in hamming do yield x * 2 }
let ys = seq { for x in hamming do yield x * 3 }
let zs = seq { for x in hamming do yield x * 5 }
yield! xs -|- ys -|- zs
}
lazyList
计算生成器的工作方式与
seq
类似,因此您可以像这样简化代码:
// 2-way merge with deduplication
let rec (-|-) (xs: LazyList<'T>) (ys: LazyList<'T>) =
let x = LazyList.head xs
let y = LazyList.head ys
let xstl = LazyList.skip 1 xs
let ystl = LazyList.skip 1 ys
if x < y then lazyList { yield x; yield! xstl -|- ys }
elif x > y then lazyList { yield y; yield! xs -|- ystl }
else lazyList { yield x; yield! xstl -|- ystl }
let rec hamming : LazyList<uint64> = lazyList {
yield 1UL
let xs = LazyList.map ((*) 2UL) hamming
let ys = LazyList.map ((*) 3UL) hamming
let zs = LazyList.map ((*) 5UL) hamming
yield! xs -|- ys -|- zs
}
[<EntryPoint>]
let main argv =
let watch = Stopwatch.StartNew ()
hamming
|> LazyList.take 2000
|> LazyList.iter (printf "%d, ")
watch.Stop ()
printfn ""
printfn "Elapsed time: %.4fms" watch.Elapsed.TotalMilliseconds
System.Console.ReadKey () |> ignore
0 // Return an integer exit code
(-|-)
函数通用,并修改了
hamming
以使用 64 位无符号整数,因为 32 位有符号整数在位后溢出)。这段代码在大约 450 毫秒内遍历了我机器上序列的前 2000 个元素;前 10000 个元素需要大约 3500 毫秒。
关于f# - F# 中 seq<int> 与 Lazy<LazyList<int>> 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24600070/
在 Scala 2.13 中,我遇到了使用运算符 #:: 进行模式匹配的问题。 ,显示错误 Cannot resolve method #::.unapply如下使用时: def exampleFun
我一直在尝试创建一系列项目的 LazyList,在本例中为 block ,必须像时尚一样以 3 维数组访问。 def getBlocks: LazyList[Block] = getBlocks(
我最近开始意识到 LazyList 的概念,我想在我的工作中实现这个概念。 我有几个方法可以从数据库中检索数十万个条目,我想返回一个 LazyList而不是典型的 List . 我只能找到 Lazy>
我在 ViewModel 中有一个通知列表。 class Notification( val id: String, val title: String, val body:
我很难确定我的问题是 Jetpack Compose 缺少功能还是我找不到它是如何完成的。 假设我想做这个页面 它需要可滚动,因为内容很长。 我还想使用惰性列来加载图像中显示的用户列表。 问题是您不能
我无法理解序列和 LazyList 之间的差异.他们既懒惰又可能无限。虽然 seq是 IEnumerable来自 .NET 框架,LazyList包含在 F# PowerPack 中.在实践中,我遇到
我一直在 Scala 中做一些欧拉问题,当我发现 #2 问题的非常优雅的解决方案时。但是,我在理解它为什么起作用时遇到了一些问题。据我所知需要 1并将其添加到 fibbonaciNumbers.sca
我正在使用 LazyList将图像加载到 ListView 中。但我只想在 ListView 中显示 Rect(8, 8, 16, 16)。是否可以将 drawbitmap 与以前下载的图像一起使用?
我目前正在使用此处的 LazyList View :https://github.com/thest1/LazyList 除了 ListView 的初始加载,一切都很好。没有图像正在加载。我实际上必须
我是 Android 应用程序的新开发人员。我正在研究显示来自 .net 数据库服务的图像。我正在使用 SoapObject 类与 .net Web 服务通信。当我将获取图像的请求发送到数据库时,它正
我已经使用惰性列表概念实现了示例应用程序。我想将所有字符串数组值分配给来自 LazyAdapter(extends BaseAdapter) 类的 TextView 我用过这个类如下 public
我正在尝试将 searchView 与 LazyList 结合使用。在我的 lazyAdapter 中,我更新了我的 arraylist,这工作顺利,但我的 listview 没有更新 arrayLi
在我的应用程序中,我有一个项目列表,我通过 LoaderManager 获取项目。当我选择或取消选择项目时,它无法正常工作,我的意思是有时不会选择所有项目。也许它会在 onLoadFinished 方
我有一个庞大的数据库,我正在尝试使用 greendao 中的 Limit 和 offset 选项执行分页。 我想要做的是,在列表中附加新的结果,其中包括使用 greenDao 查询生成器从数据库中获取
我发现 LazyList 会产生内存泄漏。当我向下滚动到列表底部时,我的应用程序的内存使用量增加了 ~3MB。向上滚动后,使用量也增加了 ~3MB。内存使用量一直增加是滚动列表。如何解决? Issue
我正在将一个项目从 Scala 2.12.1 迁移到 2.13.6,发现 SeqView#flatMap 现在返回一个 View,它没有distinct 方法。因此,我有一段代码不再编译: val n
我是 Scala 的新手,我刚刚了解到 LazyList创建是为了替换 Stream ,同时他们添加了 .view所有集合的方法。 所以,我想知道为什么 LazyList添加到 Scala 集合库,我
我对 Scala 完全陌生。我一直在玩 LazyList s。考虑以下: val fun: Int => Int = (x: Int) => { println("PROCESSING..."
我问这个问题对你们大多数人来说听起来很愚蠢,但我一直无法自己解决这个问题,并且在找到答案之前无法转移到我的下一个任务。到目前为止,我已经从 https://github.com/thest1/Lazy
我正在尝试在 android listview 中实现分页。 背景:我通过网络服务下载了大约 6 万个数据集,并使用 GreenDao 将它们保存到 SQLite 数据库中。现在我想在 ListVie
我是一名优秀的程序员,十分优秀!