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