Golang多维切片拷贝

Posted

技术标签:

【中文标题】Golang多维切片拷贝【英文标题】:Golang multidimensional slice copy 【发布时间】: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 循环,但我不确定它是否更有效。我猜应该是内置的。 谢谢,工作;)至少写得更少 我也可以稍后对其进行基准测试,因为我很想看看它的比较。 期待您的基准测试;) 如果您能给我一个提示,我该如何自己进行基准测试...谢谢 【参考方案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

【讨论】:

以上是关于Golang多维切片拷贝的主要内容,如果未能解决你的问题,请参考以下文章

Golang中切片复制成本,一个大切片会比小切片占用更多内存吗?

Golang M 2023 4 topic

Golang basic_leaming切片

Golang basic_leaming切片

Golang 切片删除指定元素的几种方法

Golang 切片删除指定元素的几种方法