gpt4 book ai didi

string - 如何在没有加号操作的情况下在 GoLang 中添加一个字符串?

转载 作者:行者123 更新时间:2023-12-01 22:31:24 25 4
gpt4 key购买 nike

这可能是重复的,但我无法在任何地方找到正确的答案。如何在不使用 + 运算符(这被认为很慢)的情况下在 GoLang 中添加字符串?

我知道我可以使用bytes.Buffer追加到一个字符串,但是WriteString只能追加。如果我想添加,我必须像这样写带有后缀字符串的前缀:

package main

import (
"bytes"
"fmt"
)

func main() {
var b bytes.Buffer

b.WriteString("W")
b.WriteString("o")
b.WriteString("r")
b.WriteString("l")
b.WriteString("d")

var a bytes.Buffer
a.WriteString("Hello ")
a.WriteString(b.String())

fmt.Println(a.String())
}

有没有更好的办法?

最佳答案

使用 strings.Builder 是可行的方法,如果它在性能关键路径 上,否则简单 + 不止于此;如果您事先知道长度,您也可以使用数组或 slice 和复制(感谢@mh-cbon,参见slice-allocation-performance):

go test -benchtime=4731808x -benchmem -bench .
BenchmarkBufferArraySimplified-8 4731808 11.36 ns/op 0 B/op 0 allocs/op
BenchmarkBufferArray-8 4731808 62.19 ns/op 0 B/op 0 allocs/op
BenchmarkBuilder-8 4731808 140.7 ns/op 32 B/op 3 allocs/op
BenchmarkBuffer-8 4731808 200.7 ns/op 128 B/op 2 allocs/op
BenchmarkByteAppend-8 4731808 223.2 ns/op 16 B/op 4 allocs/op
BenchmarkPlus-8 4731808 226.2 ns/op 16 B/op 4 allocs/op
BenchmarkByteCopy-8 4731808 254.1 ns/op 32 B/op 5 allocs/op
BenchmarkPrepend-8 4731808 273.7 ns/op 24 B/op 5 allocs/op

基准:

package main

import (
"bytes"
"strings"
"testing"
)

func BenchmarkBufferArraySimplified(b *testing.B) {
for i := 0; i < b.N; i++ {
var y [11]byte // should you know the length beforehand
y[6] = 'W'
y[7] = 'o'
y[8] = 'r'
y[9] = 'l'
y[10] = 'd'

copy(y[0:], "Hello ")
_ = string(y[:])
}
}
func BenchmarkBufferArray(b *testing.B) {
for i := 0; i < b.N; i++ {
var y [11]byte
hello := "Hello "
n := len(hello) // should you know the length beforehand
b := bytes.NewBuffer(y[:n])
b.WriteString("W")
b.WriteString("o")
b.WriteString("r")
b.WriteString("l")
b.WriteString("d")

a := bytes.NewBuffer(y[:0])
a.WriteString(hello) // prepend
_ = b.String()
}
}
func BenchmarkBuilder(b *testing.B) {
for i := 0; i < b.N; i++ {
var b strings.Builder
b.WriteString("W")
b.WriteString("o")
b.WriteString("r")
b.WriteString("l")
b.WriteString("d")

var a strings.Builder
a.WriteString("Hello ") // prepend
a.WriteString(b.String())
_ = a.String()
}
}
func BenchmarkBuffer(b *testing.B) {
for i := 0; i < b.N; i++ {
var b bytes.Buffer
b.WriteString("W")
b.WriteString("o")
b.WriteString("r")
b.WriteString("l")
b.WriteString("d")

var a bytes.Buffer
a.WriteString("Hello ") // prepend
a.WriteString(b.String())
_ = a.String()
}
}
func BenchmarkByteAppend(b *testing.B) {
for i := 0; i < b.N; i++ {
b := "W"
b += "o"
b += "r"
b += "l"
b += "d"

_ = ByteAppend("Hello ", b) // prepend
}
}
func ByteAppend(a, b string) string {
return string(append([]byte(a), []byte(b)...)) // a+b
}
func BenchmarkPlus(b *testing.B) {
for i := 0; i < b.N; i++ {
b := "W"
b += "o"
b += "r"
b += "l"
b += "d"

_ = "Hello " + b // prepend
}
}
func BenchmarkByteCopy(b *testing.B) {
for i := 0; i < b.N; i++ {
b := "W"
b += "o"
b += "r"
b += "l"
b += "d"

_ = byteCopy("Hello ", b) // prepend
}
}
func byteCopy(a, b string) string {
c := make([]byte, len(a)+len(b))
copy(c, a)
copy(c[len(a):], b) // a+b
return string(c)
}
func BenchmarkPrepend(b *testing.B) {
for i := 0; i < b.N; i++ {
b := " "
b += "W"
b += "o"
b += "r"
b += "l"
b += "d"

_ = string(prepend([]byte(b), []byte("Hello"))) // prepend
}
}

// prepend: insert b into a at index 0: len(a) >= len(b)
func prepend(a, b []byte) []byte {
// if len(a) >= len(b) {
a = append(a[:len(b)], a...) // grow
copy(a, b)
return a
// }
// return append(b, a...)
}

关于string - 如何在没有加号操作的情况下在 GoLang 中添加一个字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63564764/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com