浅析Golang中字符串拼接问题
2023-04-12 05:56:15 脚本之家
目录
1.概述2.Golang中字符串拼接的方式3.总结

1.概述

Go的字符串是一个不可改变的数据结构,这和其他语言如JAVA,C++等的设定很类似.总体来说,有如下五种拼接方式,下面我们将论述各种方式的性能问题,以及如何选择.


(相关资料图)

(golang字符串,内存模型)

type StringHeader struct {
	Data uintptr
	Len  int
}

注意:字符串具有不可改变的特性,即便通过指针等变相操作

var a string = "old"
	bptr := (*reflect.StringHeader)(unsafe.Pointer(&a))
	dataPtr := (*byte)(unsafe.Pointer(bptr.Data))
	var b = [3]byte{"n", "e", "w"}
	*dataPtr = b[0] //报错
	fmt.Println(bptr)

2.Golang中字符串拼接的方式

方式一、直接+

当使用连接符 + 拼接两个字符串时,会生成一个新的字符串并开辟新的内存空间,空间大小等于两个字符串之和。在训中中时,不断拼接新的字符串,这样就会不断申请内存空间, 性能就会越来越差。 所以,在字符串密集拼接场景中,使用 + 会严重降低性能。包括热路径的代码.

方式二、strings.Builder

func Benchmark_StringsBuilder(b *testing.B) {
	var sb strings.Builder
	for i := 0; i < b.N; i++ {
		sb.WriteString("hello world")
	}
	_ = sb.String()
}

方式三、bytes.Buffer

func Benchmark_BytesBuffer(b *testing.B) {
	var buf bytes.Buffer
	for i := 0; i < b.N; i++ {
		buf.WriteString("hello world")
	}
	_ = buf.String()
}

方式四、fmt.Fprint(&buf,&str)

方式五、strings.Join

性能不是最优,但在切片的情况下,可以用来拼接

3.总结

Benchmark_StringAdd Benchmark_StringAdd-8 117806 127059 ns/op Benchmark_BytesBuffer Benchmark_BytesBuffer-8 38938282 25.88 ns/op Benchmark_StringsBuilder Benchmark_StringsBuilder-8 57249450 18.53 ns/op

3.1 性能方面,strings.Builder 比 bytes.Buffer 快差不多 20%,

原因:strings.Builder 和 bytes.Buffer 底层都是一个 []byte,但是 bytes.Buffer 转换字符串时会重新申请内存空间用来存放, 而 strings.Builder 直接将底层的 []byte 利用指针的方式强转为字符串.

//strings.Builder的String()
func (b *Builder) String() string {
    return *(*string)(unsafe.Pointer(&b.buf))
}

//bytes.Builder的String()
func (b *Buffer) String() string {
    if b == nil {
        // Special case, useful in debugging.
        return ""
    }
    return string(b.buf[b.off:])
}

3.2 strings.Builder通常性能最优,但底层依赖于[]byte,所以如果平凡扩容就不妙了,因此我们需要借助它的Grow方法,以已分配最终[]byte的容量,避免因为扩容带来的性能损失

func Benchmark_StringConcat(b *testing.B) {
    str := "hello world"
    var sb strings.Builder
    sb.Grow(b.N * len(str))
    for i := 0; i < b.N; i++ {
        sb.WriteString(str)
    }
    _ = sb.String()
}

3.3 strings.Builder没有拷贝构造(借用C++说法),因为

type Builder struct {  
addr *Builder // of receiver, to detect copies by value  
buf []byte  //如果拷贝,这个buf共享,最后导致数据混乱
}

到此这篇关于浅析Golang中字符串拼接问题的文章就介绍到这了,更多相关Golang字符串拼接内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

热门推荐

文章排行

  1. 2023-04-12浅析Golang中字符串拼接问题
  2. 2023-04-12今日要闻!4月11日基金净值:安信优势增长混合A最新净值2.8182,跌0.2%
  3. 2023-04-11仓鼠可以喝花生牛奶吗? 微头条
  4. 2023-04-11北京丁香花几月份开?观赏期及观赏地推荐
  5. 2023-04-11知名港星晒近况!回山东老家尝遍美食,二婚妻子被指“小三”上位 最新
  6. 2023-04-11嘉定区外冈镇义务教育招生入学政策(小学+初中)|焦点热门
  7. 2023-04-11瘦腿针的价钱_瘦腿针的价格贵吗
  8. 2023-04-11请收藏!个税汇算办理步骤
  9. 2023-04-11【全球新视野】杭州社保补缴可以补缴多久之前的,离职社保能不能补缴
  10. 2023-04-11【全球时快讯】执行董事许清流增持恒安国际(01044)10万股 每股作价约36.20港元
  11. 2023-04-11环球关注:消逝的光芒2女主是谁 消逝的光芒2女主角
  12. 2023-04-11NBA常规赛已经全部结束东西部的最终排名已经确定_今日观点
  13. 2023-04-1143岁美艳女星惨死家中!8字遗书直指蒋勤勤,最后一幕令人耸人听闻 天天快看
  14. 2023-04-11厦门宏佑地产拟增资3.88亿元 对应持股比例49%|新视野
  15. 2023-04-11世界微资讯!魔兽世界猎人t2套装掉落_魔兽世界猎人t2套装
  16. 2023-04-11欲在“作战云”中飞行
  17. 2023-04-11美国3月就业趋势指数下降至116.24
  18. 2023-04-11天天热议:华强北的手表,汤主的测评来了!
  19. 2023-04-11金发碧眼的美女吸毒,产生幻觉后徒手挖掉自己双眼
  20. 2023-04-10全球微资讯!东风汽车: 东风汽车股份有限公司关于使用自有资金购买结构性存款的公告