Data structures List.permute的性能

Data structures List.permute的性能,data-structures,f#,Data Structures,F#,我最近实现了一个应用程序,它使用List.permute来洗牌列表,并注意到随着列表大小的增加,性能会显著下降。我怀疑这是由于这样一个事实,即当算法假定它在数组上运行时,permute必须通过索引访问列表元素,即O(n) 为了证实这一点,我尝试对列表应用排列以反转其元素,比较直接处理列表,并将列表转换为数组并返回列表: let permute i max = max - i - 1 let test = [ 0 .. 10000 ] let rev1 list = let perm i

我最近实现了一个应用程序,它使用List.permute来洗牌列表,并注意到随着列表大小的增加,性能会显著下降。我怀疑这是由于这样一个事实,即当算法假定它在数组上运行时,permute必须通过索引访问列表元素,即O(n)

为了证实这一点,我尝试对列表应用排列以反转其元素,比较直接处理列表,并将列表转换为数组并返回列表:

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 
我得到以下结果,这些结果倾向于证实我的假设:

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) 除了使用数组外,是否有更实用的方法/数据结构适合此类工作,即元素的无序排列?或者这仅仅是一个问题,对于这个问题,数组是正确的数据结构吗?

List.permute
。基于此,您可能会知道需要做什么(提示:使用数组!)

出于性能原因是否应避免List.permute

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

除了使用数组外,是否有更实用的方法/数据结构适合此类工作,即元素的无序排列?或者这仅仅是一个问题,对于这个问题,数组是正确的数据结构吗

您假设数组不能在功能上使用,而实际上,它们可以通过不改变元素来使用。考虑<代码>置换< /代码>函数:

let permute f (xs: _ []) = Array.init xs.Length (fun i -> xs.[f i])

虽然它作用于一个数组并生成一个数组,但它并没有改变任何东西,所以它将数组用作纯功能数据结构。

然后我不明白为什么上面的示例不能提供相同的性能-我希望第二个示例运行得同样快,或者可能会更慢,因为发生了额外的数组转换。造成差异的原因是您使用了
List.length
O(N)与
Array.length
O(1)。您是对的!我将rev1改为让l=(List.toArray List).Length和让perm I=permute I l,它现在运行得更快了。谢谢你的回答!问得好,回答得好。有时在S O上可以学到很多东西