将 [][] 字符串转换为 []byte

hss*_*hss -2 go slice

我正在尝试将 2D 字符串切片转换为 1d 字节切片,但速度非常慢。有什么更好的方法吗?,

func TwoDstringsliceToOneByteSlice(csvRecords [][]string) []byte {
    var singleSlice []byte
    for _, record := range csvRecords {
    for _, item := range record {
        singleSlice = append(singleSlice, []byte(item)...)
    }
    }
    return singleSlice
}
Run Code Online (Sandbox Code Playgroud)

kos*_*tix 5

append示例中的每个首先复制其参数 — astring和 a之间的类型转换[]byte(反之亦然)是 Go 中为数不多的复制数据的地方之一,然后很可能复制目标切片以在其中创建更多空间对于正在附加的内容。

改善这一点的一种明显方法是

func TwoDstringsliceToOneByteSlice(csvRecords [][]string) []byte {
  var buf bytes.Buffer
  for _, record := range csvRecords {
    for _, item := range record {
        buf.WriteString(item)
    }
  }
  return buf.Bytes()
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您打算将结果用于“读取”——就像使用这样的数据作为 HTTP POST 请求的有效载荷的情况一样,您可以立即使用bytes.Buffer——而无需从中取出字节片——作为bytes.Buffer实施io.Reader.

第二个改进是首先计算所有字符串的总长度,然后预分配目标切片。
然后,您可以任意调用.Grow()bytes.Buffer写,或沟之前bytes.Buffer和使用subslicing和copy(但我会反对这项建议-现在)。

…但是,正如@JimB 正确指出的那样,除非我们知道您如何衡量性能,否则很难合理猜测。

  • 另外,正如 @hobbs 在他们对您已删除的第一个问题的各自回答中指出的那样,可以实现一个阅读器,它只直接从您所说的“2D 切片”中读取,根本不执行任何转换。 (2认同)