在OCaml中设置二维数组的功能

Sof*_*mur 2 arrays ocaml memory-management multidimensional-array

我正在编写二维数组的基本函数.有两种方法可以编写"set"功能.第一个是制作矩阵的副本然后修改它:

let copy_matrix (m: 'a array array): 'a array array =
  let l = Array.length m in
    if l = 0 then m else
      let result = Array.make l m.(0) in
        for i = 0 to l - 1 do
           result.(i) <- Array.copy m.(i)
        done;
        result

let set_copy (m: 'a array array) (r: int) (c: int) (v: 'a): 'a array array =
  let m' = copy_matrix m in
  m'.(r).(c) <- v;
  m'
Run Code Online (Sandbox Code Playgroud)

第二个只是直接在矩阵上修改:

let set (m: 'a array array) (r: int) (c:int) (v: 'a) : unit =
  m.(r).(c) <- v
Run Code Online (Sandbox Code Playgroud)

我认为如果是在Java中,第二个功能显然比第一个功能更快,更经济.然而,有人(我忘了)告诉我1)OCaml的内存管理是如此聪明,set_copy不会花费太多,2)有一些原因(我忘了)使用它set_copy比使用更好set.

谁能告诉我这是否属实?

gas*_*che 5

如果你需要持久化数组(你需要保留所有版本以用于回溯目的等),复制版本当然要好得多,但它会很慢.我们在这篇StackOverflow帖子中讨论了持久化数组结构,如果你想要持久化,你应该考虑使用它们而不是普通数组.使用持久数组的持久数组处理矩阵可能会运行得相当好.当然,您也可以使用带有类型键的Map(int * int)作为起点(但访问成本是不可忽略的).

如果你不需要持久化(你永远不需要保持"旧"数组),避免复制和保持标准数据类型会更好.

此外,您可以实现matrix_copy

let matrix_copy m = Array.map Array.copy m
Run Code Online (Sandbox Code Playgroud)