更新列表元素的问题

时间:2013-12-01 19:33:27

标签: list data-structures f# task-parallel-library

以下函数旨在通过更新块中的列表元素来添加并行性,以尝试对其进行负载平衡。但是,它给我:属性'item'不能在内部循环中设置为xs。[x1]。我必须使用一个列表,因为该函数的列表是更大算法的一部分。有什么建议吗?

let pmap_tpl_parforlb f (xs:list<_>) =
    let chunkLength = xs.Length / numProc 
    Parallel.For(0,numProc, fun c ->    
        let x = c * chunkLength
        let y = (c * chunkLength) + chunkLength
        let x1 = x+1
        for x1 in 0..y-1 do
            xs.[x1] <- f (xs.[x1])
    ) |> ignore
    xs

2 个答案:

答案 0 :(得分:2)

内置的F#列表类型是不可变的,这就是您收到该错误的原因。您可以使用索引表示法(blah.[idx])来访问列表值,但它非常罕见且速度慢,因为它是O(n)操作。

从您发布的代码片段中,您似乎应该使xs成为数组而不是列表。或者,使用List.toArrayArray.ofList将列表转换为数组,然后在Parallel.For中对其进行变更。

答案 1 :(得分:0)

  1. xs.Length / numProc正在向下舍入(你正在以这种方式丢失元素,例如1/8 = 0)。
  2. 最后一个块的长度可能不是chunkLength,而是更短。你必须调和这个事实。
  3. x1不应该从0开始,而不是从1开始?
  4. 无论如何,使用调试器检查变量的运行时值,你会发现所有的错误。