最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析Golang中字符串拼接問(wèn)題

 更新時(shí)間:2023年04月11日 14:15:25   作者:落風(fēng)雪  
Go的字符串是一個(gè)不可改變的數(shù)據(jù)結(jié)構(gòu),這和其他語(yǔ)言如JAVA,C++等的設(shè)定很類(lèi)似.總體來(lái)說(shuō),有如下五種拼接方式,下面我們將論述各種方式的性能問(wèn)題,以及如何選擇

1.概述

Go的字符串是一個(gè)不可改變的數(shù)據(jù)結(jié)構(gòu),這和其他語(yǔ)言如JAVA,C++等的設(shè)定很類(lèi)似.總體來(lái)說(shuō),有如下五種拼接方式,下面我們將論述各種方式的性能問(wèn)題,以及如何選擇.

(golang字符串,內(nèi)存模型)

type StringHeader struct {
	Data uintptr
	Len  int
}

注意:字符串具有不可改變的特性,即便通過(guò)指針等變相操作

	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] //報(bào)錯(cuò)
	fmt.Println(bptr)

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

方式一、直接+

當(dāng)使用連接符 + 拼接兩個(gè)字符串時(shí),會(huì)生成一個(gè)新的字符串并開(kāi)辟新的內(nèi)存空間,空間大小等于兩個(gè)字符串之和。在訓(xùn)中中時(shí),不斷拼接新的字符串,這樣就會(huì)不斷申請(qǐng)內(nèi)存空間, 性能就會(huì)越來(lái)越差。 所以,在字符串密集拼接場(chǎng)景中,使用 + 會(huì)嚴(yán)重降低性能。包括熱路徑的代碼.

方式二、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

性能不是最優(yōu),但在切片的情況下,可以用來(lái)拼接

3.總結(jié)

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 底層都是一個(gè) []byte,但是 bytes.Buffer 轉(zhuǎn)換字符串時(shí)會(huì)重新申請(qǐng)內(nèi)存空間用來(lái)存放, 而 strings.Builder 直接將底層的 []byte 利用指針的方式強(qiáng)轉(zhuǎn)為字符串.

//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 "<nil>"
    }
    return string(b.buf[b.off:])
}

3.2 strings.Builder通常性能最優(yōu),但底層依賴(lài)于[]byte,所以如果平凡擴(kuò)容就不妙了,因此我們需要借助它的Grow方法,以已分配最終[]byte的容量,避免因?yàn)閿U(kuò)容帶來(lái)的性能損失

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沒(méi)有拷貝構(gòu)造(借用C++說(shuō)法),因?yàn)?/p>

type Builder struct {  
addr *Builder // of receiver, to detect copies by value  
buf []byte  //如果拷貝,這個(gè)buf共享,最后導(dǎo)致數(shù)據(jù)混亂
}

到此這篇關(guān)于淺析Golang中字符串拼接問(wèn)題的文章就介紹到這了,更多相關(guān)Golang字符串拼接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang結(jié)構(gòu)化日志包log/slog的使用詳解

    Golang結(jié)構(gòu)化日志包log/slog的使用詳解

    官方提供的用于打印日志的包是標(biāo)準(zhǔn)庫(kù)中的 log 包,該包雖然被廣泛使用,但是缺點(diǎn)也很多,所以Go 1.21新增的 log/slog 完美解決了以上問(wèn)題,下面我們就來(lái)看看log/slog包的使用吧
    2023-09-09
  • 詳解Golang中Channel的原理和使用技巧

    詳解Golang中Channel的原理和使用技巧

    Channel管道提供了一種機(jī)制,它在兩個(gè)并發(fā)執(zhí)行的協(xié)程之間進(jìn)行同步,并通過(guò)傳遞與該管道元素類(lèi)型相符的值來(lái)進(jìn)行通信。本文主要介紹了Channel的原理和使用技巧,需要的可以參考一下
    2022-11-11
  • GO項(xiàng)目配置與使用的方法步驟

    GO項(xiàng)目配置與使用的方法步驟

    本文主要介紹了GO項(xiàng)目配置與使用的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2022-06-06
  • go中值傳遞和指針傳遞的使用

    go中值傳遞和指針傳遞的使用

    在Go語(yǔ)言中,使用&和*可以分別取得變量的地址和值,解引用未初始化或?yàn)閚il的指針會(huì)引發(fā)空指針異常,正確的做法是先進(jìn)行nil檢查,此外,nil在Go中用于多種類(lèi)型的空值表示,值傳遞和指針傳遞各有適用場(chǎng)景,通常小型數(shù)據(jù)結(jié)構(gòu)優(yōu)先考慮值傳遞以減少解引用開(kāi)銷(xiāo)
    2024-10-10
  • Golang中匿名組合實(shí)現(xiàn)偽繼承的方法

    Golang中匿名組合實(shí)現(xiàn)偽繼承的方法

    這篇文章主要介紹了Golang中匿名組合實(shí)現(xiàn)偽繼承的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Go語(yǔ)言入門(mén)exec的基本使用示例

    Go語(yǔ)言入門(mén)exec的基本使用示例

    這篇文章主要為大家介紹了Go語(yǔ)言入門(mén)exec在go語(yǔ)言中的基本使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 詳解Opentelemetry Collector采集器

    詳解Opentelemetry Collector采集器

    這篇文章主要為大家介紹了Opentelemetry Collector神秘的采集器詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Go語(yǔ)言:打造優(yōu)雅數(shù)據(jù)庫(kù)單元測(cè)試的實(shí)戰(zhàn)指南

    Go語(yǔ)言:打造優(yōu)雅數(shù)據(jù)庫(kù)單元測(cè)試的實(shí)戰(zhàn)指南

    Go語(yǔ)言數(shù)據(jù)庫(kù)單元測(cè)試入門(mén):聚焦高效、可靠的數(shù)據(jù)庫(kù)代碼驗(yàn)證!想要確保您的Go應(yīng)用數(shù)據(jù)層堅(jiān)如磐石嗎?本指南將手把手教您如何利用Go進(jìn)行數(shù)據(jù)庫(kù)單元測(cè)試,輕松揪出隱藏的bug,打造無(wú)懈可擊的數(shù)據(jù)處理邏輯,一起來(lái)探索吧!
    2024-01-01
  • Golang實(shí)現(xiàn)延遲調(diào)用的項(xiàng)目實(shí)踐

    Golang實(shí)現(xiàn)延遲調(diào)用的項(xiàng)目實(shí)踐

    本文主要介紹了Golang實(shí)現(xiàn)延遲調(diào)用的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • jenkins配置golang?代碼工程自動(dòng)發(fā)布的實(shí)現(xiàn)方法

    jenkins配置golang?代碼工程自動(dòng)發(fā)布的實(shí)現(xiàn)方法

    這篇文章主要介紹了jenkins配置golang?代碼工程自動(dòng)發(fā)布,jks是個(gè)很好的工具,使用方法也很多,我只用了它簡(jiǎn)單的功能,對(duì)jenkins配置golang相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-07-07

最新評(píng)論

盐城市| 洛隆县| 滦平县| 和田县| 永吉县| 辽阳市| 桂东县| 宁明县| 谷城县| 原阳县| 阿坝县| 屏南县| 鄯善县| 平南县| 马尔康县| 阿瓦提县| 景宁| 正定县| 庆云县| 盐池县| 英吉沙县| 马公市| 泉州市| 上林县| 灌云县| 巴彦淖尔市| 紫阳县| 天峻县| 分宜县| 山西省| 民县| 阿克| 巴彦县| 依兰县| 雷州市| 浦北县| 南涧| 烟台市| 澄江县| 宁武县| 新绛县|