如何在没有加号操作的情况下在 GoLang 中添加一个字符串?
How to prepend a string in GoLang without plus operation?
这可能是重复的,但我无法在任何地方找到正确的答案。如何在不使用 +
运算符(这被认为很慢)的情况下在 GoLang 中添加字符串?
我知道我可以使用 bytes.Buffer
追加 到字符串,但 WriteString
只能追加。如果我想 prepend,我将不得不像这样用后缀的字符串写入前缀:
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
是可行的方法,如果它在 性能关键路径 上,否则 简单 +
不止于此;如果您事先知道长度,您也可以使用 数组或切片和复制 (感谢 @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...)
}
我 运行 遇到需要在前面添加 10,000 个字符串的情况。这与前置 10 个字符串的最快方法有点不同,但此处尚未得到解答。
TL;DR 将 10,000 个字符串存储在 []string 中,然后使用 strings.StringBuilder 到 assemble 倒序排列。
var strs []string
for i := 0; i < 10000; i++ {
strs = append(strs, "Put your string here")
}
var b strings.Builder
for i := len(strs) - 1; i >= 0; i -= 1 {
b.WriteString(strs[j])
}
+
的天真方法使用了 10 GB 的内存 + 1 秒。将相当多的时间投入到从后面填充缓冲区的自定义前置代码中,将相同的测试用例减少到 10mb + 2 毫秒。但事实证明,只需存储每个字符串,然后使用字符串构建器就可以用更少的代码实现几乎相同的结果。 (14mb 2.4 毫秒)。
这是基准测试结果:
go test -benchtime=50x -benchmem -bench .
BenchmarkPrepend10kAddition-20 50 971398162 ns/op 9666950277 B/op 20325 allocs/op
BenchmarkPrepend10kPrepender-20 50 1924394 ns/op 10165544 B/op 29913 allocs/op
BenchmarkPrepend10kReorderThenStringBuilder-20 50 2436740 ns/op 14518100 B/op 19952 allocs/op
这是代码(没有前缀 class 因为需要更多的工作才能 public 准备好):
package main
import (
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
var teststrings []string = []string{
"Test test tses test test sets etsetsetsetsettesestsetet\n",
"TEST TEST TEST TEST TEST EST SET ET SET EST EST SET E TSE TES T STE ET SETT\n",
"ashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n", "asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
}
func BenchmarkPrepend10kAddition(b *testing.B) {
for i := 0; i < b.N; i++ {
str := ""
for j := 0; j < 10000; j++ {
str = (strconv.Itoa(j) + teststrings[j%4]) + str
}
_ = string(str)
}
}
func BenchmarkPrepend10kPrepender(b *testing.B) {
for i := 0; i < b.N; i++ {
// Example using custom prepender code not included in this post
prepender := NewStringPrepender()
for j := 0; j < 10000; j++ {
prepender.Prepend(strconv.Itoa(j) + teststrings[j%4])
}
_ = string(prepender.String())
}
}
func BenchmarkPrepend10kReorderThenStringBuilder(b *testing.B) {
for i := 0; i < b.N; i++ {
// What if we have 10,000 strings and assemble them at the end?
var strs []string
for j := 0; j < 10000; j++ {
strs = append(strs, strconv.Itoa(j)+teststrings[j%4])
}
var b strings.Builder
for j := len(strs) - 1; j >= 0; j -= 1 {
b.WriteString(strs[j])
}
_ = string(b.String())
}
}
为了在基准测试中生成字符串,我使用了 Itoa + 测试字符串列表。这可能是不必要的,但我添加它们是为了确保 []string 中的值不会指向相同的内存位置。 运行domish 测试字符串会改变连接字符串的长度。
这可能是重复的,但我无法在任何地方找到正确的答案。如何在不使用 +
运算符(这被认为很慢)的情况下在 GoLang 中添加字符串?
我知道我可以使用 bytes.Buffer
追加 到字符串,但 WriteString
只能追加。如果我想 prepend,我将不得不像这样用后缀的字符串写入前缀:
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
是可行的方法,如果它在 性能关键路径 上,否则 简单 +
不止于此;如果您事先知道长度,您也可以使用 数组或切片和复制 (感谢 @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...)
}
我 运行 遇到需要在前面添加 10,000 个字符串的情况。这与前置 10 个字符串的最快方法有点不同,但此处尚未得到解答。
TL;DR 将 10,000 个字符串存储在 []string 中,然后使用 strings.StringBuilder 到 assemble 倒序排列。
var strs []string
for i := 0; i < 10000; i++ {
strs = append(strs, "Put your string here")
}
var b strings.Builder
for i := len(strs) - 1; i >= 0; i -= 1 {
b.WriteString(strs[j])
}
+
的天真方法使用了 10 GB 的内存 + 1 秒。将相当多的时间投入到从后面填充缓冲区的自定义前置代码中,将相同的测试用例减少到 10mb + 2 毫秒。但事实证明,只需存储每个字符串,然后使用字符串构建器就可以用更少的代码实现几乎相同的结果。 (14mb 2.4 毫秒)。
这是基准测试结果:
go test -benchtime=50x -benchmem -bench .
BenchmarkPrepend10kAddition-20 50 971398162 ns/op 9666950277 B/op 20325 allocs/op
BenchmarkPrepend10kPrepender-20 50 1924394 ns/op 10165544 B/op 29913 allocs/op
BenchmarkPrepend10kReorderThenStringBuilder-20 50 2436740 ns/op 14518100 B/op 19952 allocs/op
这是代码(没有前缀 class 因为需要更多的工作才能 public 准备好):
package main
import (
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
var teststrings []string = []string{
"Test test tses test test sets etsetsetsetsettesestsetet\n",
"TEST TEST TEST TEST TEST EST SET ET SET EST EST SET E TSE TES T STE ET SETT\n",
"ashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n", "asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
"asdhakjsdhaksjdhdskajhsdajkshdkajshdkjasdkjdhasfhjadshfashdasgfkjashdgfjhsadgfjashgdfkjhasgdfkjhgasdfkjghasdfkjhgasdkjfhgasdkjghfasdkjghfasdhjfgasjkghfsadhjgfaashkajshfksjhdfksjdhfklhjasdfkljhasdfljashdfkljahsdfkjshafdkjashdflkjhsdgkljhsdfklgjhsklfjghksdfjgkldsjfghldksjhfgkdsfjghkdsjhfgkldjsghkldsjfghdklsfgasdjhaksdhjaksdjhasdkjhfksdjhfkjashfdjldhjasfkljashdfkljsahdflkjashdfldhjasfkjsdhf\n",
}
func BenchmarkPrepend10kAddition(b *testing.B) {
for i := 0; i < b.N; i++ {
str := ""
for j := 0; j < 10000; j++ {
str = (strconv.Itoa(j) + teststrings[j%4]) + str
}
_ = string(str)
}
}
func BenchmarkPrepend10kPrepender(b *testing.B) {
for i := 0; i < b.N; i++ {
// Example using custom prepender code not included in this post
prepender := NewStringPrepender()
for j := 0; j < 10000; j++ {
prepender.Prepend(strconv.Itoa(j) + teststrings[j%4])
}
_ = string(prepender.String())
}
}
func BenchmarkPrepend10kReorderThenStringBuilder(b *testing.B) {
for i := 0; i < b.N; i++ {
// What if we have 10,000 strings and assemble them at the end?
var strs []string
for j := 0; j < 10000; j++ {
strs = append(strs, strconv.Itoa(j)+teststrings[j%4])
}
var b strings.Builder
for j := len(strs) - 1; j >= 0; j -= 1 {
b.WriteString(strs[j])
}
_ = string(b.String())
}
}
为了在基准测试中生成字符串,我使用了 Itoa + 测试字符串列表。这可能是不必要的,但我添加它们是为了确保 []string 中的值不会指向相同的内存位置。 运行domish 测试字符串会改变连接字符串的长度。