【问题标题】:Golang multidimensional slice copyGolang多维切片拷贝
【发布时间】:2018-01-09 22:43:05
【问题描述】:

我试图复制多维切片,因为当我更改了复制切片中的元素时,原始切片中的元素也被覆盖了。

唯一对我有用的方法是:

duplicate := make([][]int, len(matrix))
for i := 0; i < len(matrix); i++ {
    duplicate[i] = make([]int, len(matrix[0]))
    for j := 0; j < len(matrix[0]); j++ {
        duplicate[i][j] = matrix[i][j]
    }
}

还有其他方法 - 更短或更有效地达到相同的结果吗?谢谢

【问题讨论】:

  • 您可以使用 golang.org/pkg/builtin/#copy 消除内部 for 循环,但我不确定它是否更有效。我猜应该是内置的。
  • 谢谢,工作;)至少写得更少
  • 我也可以稍后对其进行基准测试,因为我很想看看它的比较。
  • 期待您的基准测试;) 如果您能给我一个提示,我该如何自己进行基准测试...谢谢

标签: go multidimensional-array slice


【解决方案1】:

您可以将 copy 用于内部循环(应该更有效),将 range 用于外部循环(这会产生更好的代码)。

结果:

duplicate := make([][]int, len(matrix))
for i := range matrix {
    duplicate[i] = make([]int, len(matrix[i]))
    copy(duplicate[i], matrix[i])
}

如果您的目标是效率,那么预先进行更多分配可能是有意义的。这不会产生更易读的代码,但如果你经常这样做,会产生更高效的代码。此代码假定您至少有一行并且所有行的长度相同。您需要为此添加测试。

n := len(matrix)
m := len(matrix[0])
duplicate := make([][]int, n)
data := make([]int, n*m)
for i := range matrix {
    start := i*m
    end := start + m
    duplicate[i] = data[start:end:end]
    copy(duplicate[i], matrix[i])
}

根据您的工作,制作仅使用单个切片实现的“矩阵类型”可能是有意义的。切片切片并不是最有效的数据结构,即使使用起来更简单。


在决定是否需要提高效率之前,请确保您花费大量时间使用分析进行复制。然后,在您确定这实际上是一个热点之后,开始运行基准测试。详情请见https://golang.org/pkg/testing/#hdr-Benchmarks

【讨论】:

  • 哈,如果我知道我会得到那么容易的代表,我会自己完成一个完整的答案。值得称赞的是,这确实是一个非常好的答案。
  • 顺便说一句,关于使用单个切片的警告注释。如果您碰巧修改了矩阵的xy 长度,那么尝试使用平面矩阵是个坏主意。
  • 好点,刚刚通过添加上限解决了这个问题。尽管如此,这意味着这些切片中的任何一个都可以防止整个事物被垃圾收集。虽然这会减少收集器的工作量,但也可能导致无法收集的数据无法收集。
【解决方案2】:

你可以通过 gob 来回它:

package main

import (
   "bytes"
   "encoding/gob"
   "fmt"
)

func sliceCopy(in, out interface{}) {
   buf := new(bytes.Buffer)
   gob.NewEncoder(buf).Encode(in)
   gob.NewDecoder(buf).Decode(out)
}

func main() {
   a := [][]int{
      {1, 2, 3}, {4, 5, 6}, {7, 8, 9},
   }
   var b [][]int
   sliceCopy(a, &b)
   fmt.Println(b)
}

https://golang.org/pkg/encoding/gob

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 2013-10-04
    • 1970-01-01
    • 2015-01-19
    • 2019-01-12
    • 2012-08-06
    相关资源
    最近更新 更多