zoukankan      html  css  js  c++  java
  • 【原】golang 中字符串拼接的方式性能对比

    背景

        开发过程中,常常会用到字符串拼接完成某种需求,我们能马上想到的解决办法有+,fmt.Sprintf,高级一点可能还会想到strings包的Join 方法,甚至想到bytes.buffer,再用writeString 方法完成,再而想到strings.builder。但究竟哪种效率高呢?我们在使用过程中如何选择?只有实测才知道

    结论

        测试结论 bytes.Buffer > + > strings.Join > strings.builder > fmt.Sprintf 。

        简单拼接用+,复杂,追求高效用bytes.Buffer

    实测

        以下测试在个人mac 系统下。go 版本1.15,不同版本可能略有不同,以自己实际输出为准。

    测试1

     

    package strings

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

    func BenchmarkStringBuild(b *testing.B) {
    hello := "hello"
    world := "world"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    var result strings.Builder
    result.WriteString(hello)
    result.WriteString(world)
    //result.WriteString("aaa")
    //result.WriteString(strconv.Itoa(10000))
    }
    }

    func BenchmarkStringJia(b *testing.B) {
    hello := "hello"
    world := "world"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    //_ = hello + world + "aaa !" + strconv.Itoa(10000)
    _ = hello + world
    }
    }

    func BenchmarkStringSprintf(b *testing.B) {
    hello := "hello"
    world := "world"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    //_ = fmt.Sprintf("%s,%s,%s,%d", hello, world, "aaa !", 1000)
    _ = fmt.Sprintf("%s,%s", hello, world)
    }
    }

    func BenchmarkAddStringWithJoin(b *testing.B) {
    hello := "hello"
    world := "world"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    //_ = strings.Join([]string{hello, world, "aaa !", strconv.Itoa(10000)}, ",")
    _ = strings.Join([]string{hello, world}, ",")
    }
    }

    func BenchmarkAddStringWithBuffer(b *testing.B) {
    hello := "hello"
    world := "world"
    for i := 0; i < 1000; i++ {
    var buffer bytes.Buffer
    buffer.WriteString(hello)
    buffer.WriteString(",")
    buffer.WriteString(world)
    //buffer.WriteString("aaa !")
    //buffer.WriteString(strconv.Itoa(10000))
    _ = buffer.String()
    }
    }

     

     

    测试2

     

     

    package strings

    import (
    "bytes"
    "fmt"
    "strconv"
    "strings"
    "testing"
    )

    func BenchmarkStringBuild(b *testing.B) {
    hello := "hello"
    world := "world"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    var result strings.Builder
    result.WriteString(hello)
    result.WriteString(world)
    result.WriteString("aaa")
    result.WriteString(strconv.Itoa(10000))
    }
    }

    func BenchmarkStringJia(b *testing.B) {
    hello := "hello"
    world := "world"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    _ = hello + world + "aaa !" + strconv.Itoa(10000)
    //_ = hello + world
    }
    }

    func BenchmarkStringSprintf(b *testing.B) {
    hello := "hello"
    world := "world"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    _ = fmt.Sprintf("%s,%s,%s,%d", hello, world, "aaa !", 1000)
    //_ = fmt.Sprintf("%s,%s", hello, world)
    }
    }

    func BenchmarkAddStringWithJoin(b *testing.B) {
    hello := "hello"
    world := "world"
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    _ = strings.Join([]string{hello, world, "aaa !", strconv.Itoa(10000)}, ",")
    //_ = strings.Join([]string{hello, world}, ",")
    }
    }

    func BenchmarkAddStringWithBuffer(b *testing.B) {
    hello := "hello"
    world := "world"
    for i := 0; i < 1000; i++ {
    var buffer bytes.Buffer
    buffer.WriteString(hello)
    buffer.WriteString(",")
    buffer.WriteString(world)
    buffer.WriteString("aaa !")
    buffer.WriteString(strconv.Itoa(10000))
    _ = buffer.String()
    }
    }

     

     

    执行:$ go test -bench=. -benchmem -run=none

    结果显而易见,即便我只拼接hello world,不同方式的对比差异也是显著的。

    可看到

    • string.Builder内存分配4次,分配字节数64字节
    • + 进行内存分配1次,分配字节数5字节
    • fmt.Sprintf 进行内存分配3次,分配字节数64字节
    • strings.Join 进行内存分配2次,分配字节数37字节
    • bytes.Buffer WriteString进行内存分配0次,分配字节数0

    结果一般没想到的是+ 在1.15版本性能是大于 strings.Join 和fmt.Sprintf的。所以在我们使用中优先选择bytes.Buffer WriteString、其次简单的,方便阅读和编写可用+。

  • 相关阅读:
    tomcat7项目启动报错java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory
    Android APP 分享图片文字到微信刚開始正常,后面就不弹出分享框了
    Akka 编程: 什么是Actor
    【3C认证】安防产品3C认证
    设计模式之装饰模式
    关于那些常见的坑爹的小bug(会持续更新)
    【Mac双系统设置系统默认启动系统】解决方式
    JEECG常见问题大全征集
    关于最新的Vuforia-unity3d-samples2-8-13
    python-print
  • 原文地址:https://www.cnblogs.com/already/p/13686154.html
Copyright © 2011-2022 走看看