首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >List.permute的性能

List.permute的性能
EN

Stack Overflow用户
提问于 2012-04-21 02:42:35
回答 2查看 278关注 0票数 5

我最近实现了一个Fisher-Yates shuffle,它使用List.permute来混洗列表,并注意到随着列表大小的增加,性能会显著下降。我怀疑这是因为,虽然算法假设它在一个数组上操作,但permute必须通过索引访问列表元素,索引为O(n)。

为了确认这一点,我尝试将置换应用于列表以反转其元素,比较直接在列表上工作,并将列表转换为数组,然后再转换回列表:

代码语言:javascript
复制
let permute i max = max - i - 1
let test = [ 0 .. 10000 ]

let rev1 list =
   let perm i = permute i (List.length list)
   List.permute perm list

let rev2 list =
   let array = List.toArray list
   let perm i = permute i (Array.length array)
   Array.permute perm array |> Array.toList 

我得到了以下结果,这些结果倾向于证实我的假设:

代码语言:javascript
复制
rev1 test;;
Real: 00:00:00.283, CPU: 00:00:00.265, GC gen0: 0, gen1: 0, gen2: 0
rev2 test;;
Real: 00:00:00.003, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0

我的问题如下:

1)出于性能原因,是否应该避免使用List.permute?而且,与之相关的是,List.permute的实现不应该在幕后自动转换为数组吗?

2)除了使用数组之外,是否有更有效的方式/数据结构适用于这种类型的工作,即元素的混洗?或者这仅仅是一个问题,对于这个问题,使用Array是正确的数据结构?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-21 02:47:06

List.permute converts the list to an array, calls Array.permute, then converts it back to a list.在此基础上,您可能可以确定需要做什么(提示:使用数组!)。

票数 7
EN

Stack Overflow用户

发布于 2012-04-22 18:39:08

出于性能原因,是否应该避免使用List.permute?

这里唯一的性能问题是您自己的代码,特别是调用List.length

除了使用数组之外,有没有更有效的方式/数据结构适合这种类型的工作,也就是元素的混洗?或者这仅仅是一个问题,对于这个问题,使用Array是正确的数据结构?

您假设数组不能在函数上使用,而实际上,它们可以通过不改变其元素来使用。考虑permute函数:

代码语言:javascript
复制
let permute f (xs: _ []) = Array.init xs.Length (fun i -> xs.[f i])

尽管它作用于一个数组并产生一个数组,但它没有改变任何东西,所以它使用一个数组作为纯函数数据结构。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10251744

复制
相关文章

相似问题

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