转换大小写,然后连接字符串



我有一个类似的切片

v := []string{"this", "is", "a", "sample", "string"}

我想创建ThisIsASampleString。我能想到的唯一方法是首先在切片中循环,将它们转换为标题大小写,然后加入它们,即

x := []string{}
for _, s := range v {
x = append(x, strings.Title(s))
}
strings.Join(x[0:], "")

有更好的方法吗?

Benchmark(go版本go1.15.6 linux/amd64(:

BenchmarkBuilder-8     1480506  792 ns/op  112 B/op  8 allocs/op
BenchmarkBuffer-8      1500859  843 ns/op  144 B/op  7 allocs/op
BenchmarkJoin-8        1350139  938 ns/op  160 B/op  7 allocs/op
BenchmarkReplaceAll-8  1513950  793 ns/op  128 B/op  4 allocs/op
BenchmarkLoop-8        2322938  536 ns/op  112 B/op  2 allocs/op

  1. 使用strings.Builder
sb := new(strings.Builder)
for _, s := range v {
sb.WriteString(strings.Title(s))
}
st := sb.String()

  1. 使用bytes.Buffer
p := new(bytes.Buffer)
for _, s := range v {
p.WriteString(strings.Title(s))
}
st = p.String()

  1. 使用strings.Join(x, "")
x := make([]string, len(v))
for i, s := range v {
x[i] = strings.Title(s)
}
st = strings.Join(x, "")

  1. 一行(注意:输入元素内没有空格(
st = strings.ReplaceAll(strings.Title(strings.Join(v, " ")), " ", "")

  1. 基本循环:
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

最新更新