String 转换大小写,然后连接字符串
我有一片像这样的String 转换大小写,然后连接字符串,string,go,concatenation,String,Go,Concatenation,我有一片像这样的 v:=[]字符串{“this”、“is”、“a”、“sample”、“string”} 我想创建这是SampleString。我能想到的唯一方法是首先循环通过切片,将它们转换为标题大小写,然后将它们连接起来,即 x:=[]字符串{} 对于uz,s:=范围v{ x=附加(x,strings.Title) } strings.Join(x[0:],“”) 有更好的方法吗?基准测试(go版本go1.15.6 linux/amd64): 使用strings.Builder: 使
v:=[]字符串{“this”、“is”、“a”、“sample”、“string”}
我想创建这是SampleString
。我能想到的唯一方法是首先循环通过切片,将它们转换为标题大小写,然后将它们连接起来,即
x:=[]字符串{}
对于uz,s:=范围v{
x=附加(x,strings.Title)
}
strings.Join(x[0:],“”)
有更好的方法吗?基准测试(go版本go1.15.6 linux/amd64):
strings.Builder
:字节缓冲区:
字符串。连接(x,”)
:代码: 输出:
goos: linux
goarch: amd64
BenchmarkBuilder-8 1000000 809 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 812 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 753 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 823 ns/op 112 B/op 8 allocs/op
BenchmarkBuffer-8 1000000 845 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 768 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 805 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 811 ns/op 144 B/op 7 allocs/op
BenchmarkJoin-8 1000000 930 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 936 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 896 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 876 ns/op 160 B/op 7 allocs/op
BenchmarkReplaceAll-8 1000000 793 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 759 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 765 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 781 ns/op 128 B/op 4 allocs/op
BenchmarkLoop-8 1000000 535 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 530 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 506 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 487 ns/op 112 B/op 2 allocs/op
PASS
ok 15.250s
基准测试(go版本go1.15.6 linux/amd64):
strings.Builder
:字节缓冲区:
字符串。连接(x,”)
:代码: 输出:
goos: linux
goarch: amd64
BenchmarkBuilder-8 1000000 809 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 812 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 753 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 823 ns/op 112 B/op 8 allocs/op
BenchmarkBuffer-8 1000000 845 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 768 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 805 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 811 ns/op 144 B/op 7 allocs/op
BenchmarkJoin-8 1000000 930 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 936 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 896 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 876 ns/op 160 B/op 7 allocs/op
BenchmarkReplaceAll-8 1000000 793 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 759 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 765 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 781 ns/op 128 B/op 4 allocs/op
BenchmarkLoop-8 1000000 535 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 530 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 506 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 487 ns/op 112 B/op 2 allocs/op
PASS
ok 15.250s
我会考虑字节、缓冲区或字符串。Builder有效地连接字符串。下面是一个使用
我会考虑字节、缓冲区或字符串。Builder有效地连接字符串。下面是一个使用
一、 更轻微的是,更新了您的帖子,以提供完全可复制的基准。我还添加了-benchmem参数。最后我添加了(我的)go版本。时间基准测试很有趣,但由于这是一个公开的基准测试,没有人拥有相同的设备,测量时间就没那么有趣了,拥有关于算法行为(分配)的内在信息更有用。感谢@mh cbon,这真的很有帮助。我,不仅仅是一点点,更新您的帖子以提供完全可复制的基准。我还添加了-benchmem参数。最后我添加了(我的)go版本。对时间进行基准测试很有趣,但由于这是一个公共基准,没有人拥有相同的设备,因此测量时间并不那么有趣,因为它具有关于行为(分配)的内在信息算法的版本更有用。谢谢@mh cbon,这非常有用。请给我们您的
go版本
。go版本go1.15.6 linux/amd64请给我们您的go版本
。go版本go1.15.6 linux/amd64
p := new(bytes.Buffer)
for _, s := range v {
p.WriteString(strings.Title(s))
}
st = p.String()
x := make([]string, len(v))
for i, s := range v {
x[i] = strings.Title(s)
}
st = strings.Join(x, "")
st = strings.ReplaceAll(strings.Title(strings.Join(v, " ")), " ", "")
n := 0
for _, s := range v {
n += len(s)
}
x := make([]rune, 0, n)
for _, s := range v {
for i, r := range s {
if i == 0 {
r = unicode.ToUpper(r)
}
x = append(x, r)
}
}
st = string(x)
package main
import (
"bytes"
"strings"
"testing"
"unicode"
)
func BenchmarkBuilder(b *testing.B) {
for i := 0; i < b.N; i++ {
sb := new(strings.Builder)
for _, s := range v {
sb.WriteString(strings.Title(s))
}
st = sb.String()
}
}
func BenchmarkBuffer(b *testing.B) {
for i := 0; i < b.N; i++ {
p := new(bytes.Buffer)
for _, s := range v {
p.WriteString(strings.Title(s))
}
st = p.String()
}
}
func BenchmarkJoin(b *testing.B) {
for i := 0; i < b.N; i++ {
x := make([]string, len(v))
for i, s := range v {
x[i] = strings.Title(s)
}
st = strings.Join(x, "")
}
}
func BenchmarkReplaceAll(b *testing.B) {
for i := 0; i < b.N; i++ {
st = strings.ReplaceAll(strings.Title(strings.Join(v, " ")), " ", "")
}
}
func BenchmarkLoop(b *testing.B) {
for i := 0; i < b.N; i++ {
n := 0
for _, s := range v {
n += len(s)
}
x := make([]rune, 0, n)
for _, s := range v {
for i, r := range s {
if i == 0 {
r = unicode.ToUpper(r)
}
x = append(x, r)
}
}
st = string(x)
}
}
var v = []string{"this", "is", "a", "sample", "string"}
var st string
go test -v -bench=. -count=4 -benchmem -benchtime=1000000x
goos: linux
goarch: amd64
BenchmarkBuilder-8 1000000 809 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 812 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 753 ns/op 112 B/op 8 allocs/op
BenchmarkBuilder-8 1000000 823 ns/op 112 B/op 8 allocs/op
BenchmarkBuffer-8 1000000 845 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 768 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 805 ns/op 144 B/op 7 allocs/op
BenchmarkBuffer-8 1000000 811 ns/op 144 B/op 7 allocs/op
BenchmarkJoin-8 1000000 930 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 936 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 896 ns/op 160 B/op 7 allocs/op
BenchmarkJoin-8 1000000 876 ns/op 160 B/op 7 allocs/op
BenchmarkReplaceAll-8 1000000 793 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 759 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 765 ns/op 128 B/op 4 allocs/op
BenchmarkReplaceAll-8 1000000 781 ns/op 128 B/op 4 allocs/op
BenchmarkLoop-8 1000000 535 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 530 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 506 ns/op 112 B/op 2 allocs/op
BenchmarkLoop-8 1000000 487 ns/op 112 B/op 2 allocs/op
PASS
ok 15.250s
package main
import (
"testing"
)
var v = []string{"this", "is", "a", "sample", "string"}
func BenchmarkWithBuilder(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
UsingBuilder(v)
}
}
func BenchmarkWithBuffer(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
UsingBuffer(v)
}
}
// Since Go 1.10 has strings.Builder.
func UsingBuilder(v []string) string {
var builder strings.Builder
for _, s := range v {
builder.WriteString(strings.Title(s))
}
return builder.String()
}
// pre Go 1.10 the most effective way was to use bytes.Buffer
func UsingBuffer(v []string) string {
var buffer bytes.Buffer
for _, s := range v {
buffer.WriteString(strings.Title(s))
}
return buffer.String()
}
$ go test -v -bench=. -count=4 -benchmem
goos: linux
goarch: amd64
pkg: test/bench
BenchmarkWithBuilder
BenchmarkWithBuilder-4 1294498 905 ns/op 112 B/op 8 allocs/op
BenchmarkWithBuilder-4 1307007 911 ns/op 112 B/op 8 allocs/op
BenchmarkWithBuilder-4 1313634 911 ns/op 112 B/op 8 allocs/op
BenchmarkWithBuilder-4 1308748 909 ns/op 112 B/op 8 allocs/op
BenchmarkWithBuffer
BenchmarkWithBuffer-4 1388026 869 ns/op 144 B/op 7 allocs/op
BenchmarkWithBuffer-4 1389976 867 ns/op 144 B/op 7 allocs/op
BenchmarkWithBuffer-4 1380103 860 ns/op 144 B/op 7 allocs/op
BenchmarkWithBuffer-4 1380252 874 ns/op 144 B/op 7 allocs/op
PASS
ok test/bench 16.796s
$ go version
go version go1.15.2 linux/amd64