成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > Go語言模型:string的底層數(shù)據(jù)結(jié)構(gòu)與高效操作詳解

Go語言模型:string的底層數(shù)據(jù)結(jié)構(gòu)與高效操作詳解

熱門標(biāo)簽:寧波語音外呼系統(tǒng)公司 湛江crm外呼系統(tǒng)排名 仙桃400電話辦理 地圖標(biāo)注免費定制店 不封卡外呼系統(tǒng) 宿遷便宜外呼系統(tǒng)代理商 鄭州智能語音電銷機(jī)器人價格 重慶慶云企業(yè)400電話到哪申請 上海極信防封電銷卡價格

Golang的string類型底層數(shù)據(jù)結(jié)構(gòu)簡單,本質(zhì)也是一個結(jié)構(gòu)體實例,且是const不可變。

string的底層數(shù)據(jù)結(jié)構(gòu)

通過下面一個例子來看:

package main
import (
	"fmt"
	"unsafe"
)
// from: string.go 在GoLand IDE中雙擊shift快速找到
type stringStruct struct {
	array unsafe.Pointer // 指向一個 [len]byte 的數(shù)組
	length int    // 長度
}
func main() {
	test := "hello"
	p := (*str)(unsafe.Pointer(test))
	fmt.Println(p, p) // 0xc420070018 {0xa3f71 5}
	c := make([]byte, p.length)
	for i := 0; i  p.length; i++ {
		tmp := uintptr(unsafe.Pointer(p.array))   // 指針類型轉(zhuǎn)換通過unsafe包
		c[i] = *(*byte)(unsafe.Pointer(tmp + uintptr(i))) // 指針運算只能通過uintptr
	}
	fmt.Println(c)   // [104 101 108 108 111]
	fmt.Println(string(c)) // [byte] --> string, "hello"
	test2 := test + " world" // 字符串是不可變類型,會生成一個新的string實例
	p2 := (*str)(unsafe.Pointer(test2))
	fmt.Println(p2, p2) // 0xc420028030 {0xc42000a2e5 11}
	fmt.Println(test2) // hello, world
}

string的拼接與修改

+操作

string類型是一個不可變類型,那么任何對string的修改都會新生成一個string的實例,如果是考慮效率的場景就要好好考慮一下如何修改了。先說一下最長用的+操作,同樣上面的例子,看一下+操作拼接字符串的反匯編:

25		test2 := test + " world"
 0x00000000004824d7 +1127>:	lea 0x105a2(%rip),%rax  # 0x492a80
 0x00000000004824de +1134>:	mov %rax,(%rsp)
 0x00000000004824e2 +1138>:	callq 0x40dda0 runtime.newobject> # 調(diào)用newobject函數(shù)
 0x00000000004824e7 +1143>:	mov 0x8(%rsp),%rax
 0x00000000004824ec +1148>:	mov %rax,0xa0(%rsp)
 0x00000000004824f4 +1156>:	mov 0xa8(%rsp),%rax
 0x00000000004824fc +1164>:	mov 0x8(%rax),%rcx
 0x0000000000482500 +1168>:	mov (%rax),%rax
 0x0000000000482503 +1171>:	mov %rax,0x8(%rsp)
 0x0000000000482508 +1176>:	mov %rcx,0x10(%rsp)
 0x000000000048250d +1181>:	movq $0x0,(%rsp)
 0x0000000000482515 +1189>:	lea 0x30060(%rip),%rax  # 0x4b257c
 0x000000000048251c +1196>:	mov %rax,0x18(%rsp)
 0x0000000000482521 +1201>:	movq $0x6,0x20(%rsp)
 0x000000000048252a +1210>:	callq 0x43cc00 runtime.concatstring2> # 調(diào)用concatstring2函數(shù)

因為當(dāng)前go[2018.11 version: go1.11]的不是遵循默認(rèn)的x86 calling convention用寄存器傳參,而是通過stack進(jìn)行傳參,所以go的反匯編不像c的那么容易理解,不過大概看懂+背后的操作還是沒問題的,看一下runtime源碼的拼接函數(shù):

func concatstring2(buf *tmpBuf, a [2]string) string {
 return concatstrings(buf, a[:])
}
// concatstrings implements a Go string concatenation x+y+z+...
// The operands are passed in the slice a.
// If buf != nil, the compiler has determined that the result does not
// escape the calling function, so the string data can be stored in buf
// if small enough.
func concatstrings(buf *tmpBuf, a []string) string {
 idx := 0
 l := 0
 count := 0
 for i, x := range a {
  n := len(x)
  if n == 0 {
   continue
  }
  if l+n  l {
   throw("string concatenation too long")
  }
  l += n
  count++
  idx = i
 }
 if count == 0 {
  return ""
 }
 // If there is just one string and either it is not on the stack
 // or our result does not escape the calling frame (buf != nil),
 // then we can return that string directly.
 if count == 1  (buf != nil || !stringDataOnStack(a[idx])) {
  return a[idx]
 }
 s, b := rawstringtmp(buf, l)
 for _, x := range a {
  copy(b, x) // 最關(guān)鍵的拷貝操作
  b = b[len(x):]
 }
 return s
}

分析runtime的concatstrings實現(xiàn),可以看出+最后新申請buf,拷貝原來的string到buf,最后返回新實例。那么每次的+操作,都會涉及新申請buf,然后是對應(yīng)的copy。如果反復(fù)使用+,就不可避免有大量的申請內(nèi)存操作,對于大量的拼接,性能就會受到影響了。

bytes.Buffer

通過看源碼,bytes.Buffer 增長buffer時是按照2倍來增長內(nèi)存,可以有效避免頻繁的申請內(nèi)存,通過一個例子來看:

func main() {
 var buf bytes.Buffer
 for i := 0; i  10; i++ {
  buf.WriteString("hi ")
 }
 fmt.Println(buf.String())
}

對應(yīng)的byte包庫函數(shù)源碼

// @file: buffer.go
func (b *Buffer) WriteString(s string) (n int, err error) {
 b.lastRead = opInvalid
 m, ok := b.tryGrowByReslice(len(s))
 if !ok {
  m = b.grow(len(s)) // 高效的增長策略 -> let capacity get twice as large
 }
 return copy(b.buf[m:], s), nil
}
// @file: buffer.go
// let capacity get twice as large !!!
func (b *Buffer) grow(n int) int {
 m := b.Len()
 // If buffer is empty, reset to recover space.
 if m == 0  b.off != 0 {
  b.Reset()
 }
 // Try to grow by means of a reslice.
 if i, ok := b.tryGrowByReslice(n); ok {
  return i
 }
 // Check if we can make use of bootstrap array.
 if b.buf == nil  n = len(b.bootstrap) {
  b.buf = b.bootstrap[:n]
  return 0
 }
 c := cap(b.buf)
 if n = c/2-m {
  // We can slide things down instead of allocating a new
  // slice. We only need m+n = c to slide, but
  // we instead let capacity get twice as large so we
  // don't spend all our time copying.
  copy(b.buf, b.buf[b.off:])
 } else if c > maxInt-c-n {
  panic(ErrTooLarge)
 } else {
  // Not enough space anywhere, we need to allocate.
  buf := makeSlice(2*c + n)
  copy(buf, b.buf[b.off:])
  b.buf = buf
 }
 // Restore b.off and len(b.buf).
 b.off = 0
 b.buf = b.buf[:m+n]
 return m
}

string.join

這個函數(shù)可以一次申請最終string的大小,但是使用得預(yù)先準(zhǔn)備好所有string,這種場景也是高效的,一個例子:

func main() {
 var strs []string
 for i := 0; i  10; i++ {
 strs = append(strs, "hi")
 }
 fmt.Println(strings.Join(strs, " "))
}

對應(yīng)庫的源碼:

// Join concatenates the elements of a to create a single string. The separator string
// sep is placed between elements in the resulting string.
func Join(a []string, sep string) string {
 switch len(a) {
 case 0:
  return ""
 case 1:
  return a[0]
 case 2:
  // Special case for common small values.
  // Remove if golang.org/issue/6714 is fixed
  return a[0] + sep + a[1]
 case 3:
  // Special case for common small values.
  // Remove if golang.org/issue/6714 is fixed
  return a[0] + sep + a[1] + sep + a[2]
 }
 
 // 計算好最終的string的大小
 n := len(sep) * (len(a) - 1) //
 for i := 0; i  len(a); i++ {
  n += len(a[i])
 }
 b := make([]byte, n)
 bp := copy(b, a[0])
 for _, s := range a[1:] {
  bp += copy(b[bp:], sep)
  bp += copy(b[bp:], s)
 }
 return string(b)
}

strings.Builder (go1.10+)

看到這個名字,就想到了Java的庫,哈哈,這個Builder用起來是最方便的,不過是在1.10后引入的。其高效也是體現(xiàn)在2倍速的內(nèi)存增長, WriteString函數(shù)利用了slice類型對應(yīng)append函數(shù)的2倍速增長。

一個例子:

func main() {
 var s strings.Builder
 for i := 0; i  10; i++ {
  s.WriteString("hi ")
 }
 fmt.Println(s.String())
}

對應(yīng)庫的源碼

@file: builder.go
// WriteString appends the contents of s to b's buffer.
// It returns the length of s and a nil error.
func (b *Builder) WriteString(s string) (int, error) {
 b.copyCheck()
 b.buf = append(b.buf, s...)
 return len(s), nil
}

總結(jié)

Golang的字符串處理還是挺方便的,有垃圾回收和一些內(nèi)置的語言級寫法支持,讓復(fù)雜字符串操作沒有那么繁瑣了,比起C/C++高效了不少。

補(bǔ)充:go string的內(nèi)部實現(xiàn)

go string 內(nèi)部實現(xiàn)

這個string的探索

來來個例子

func boo(a int, b int)(int, string){
 return a + b, "abcd"
}
81079 000000000044dfa0 main.boo>:
81080 44dfa0:>------48 c7 44 24 18 00 00 >--movq $0x0,0x18(%rsp)
81081 44dfa7:>------00 00- 
81082 44dfa9:>------0f 57 c0    >--xorps %xmm0,%xmm0
81083 44dfac:>------0f 11 44 24 20  >--movups %xmm0,0x20(%rsp)
81084 44dfb1:>------48 8b 44 24 08  >--mov 0x8(%rsp),%rax
81085 44dfb6:>------48 03 44 24 10  >--add 0x10(%rsp),%rax
81086 44dfbb:>------48 89 44 24 18  >--mov %rax,0x18(%rsp)
81087 44dfc0:>------48 8d 05 d4 eb 01 00 >--lea 0x1ebd4(%rip),%rax  # 46cb9b go.string.*+0xbb>
81088 44dfc7:>------48 89 44 24 20  >--mov %rax,0x20(%rsp)
81089 44dfcc:>------48 c7 44 24 28 04 00 >--movq $0x4,0x28(%rsp)
81090 44dfd3:>------00 00- 
81091 44dfd5:>------c3     >--retq---

其中

81087 44dfc0:>------48 8d 05 d4 eb 01 00 >--lea 0x1ebd4(%rip),%rax  # 46cb9b go.string.*+0xbb>
81088 44dfc7:>------48 89 44 24 20  >--mov %rax,0x20(%rsp)
81089 44dfcc:>------48 c7 44 24 28 04 00 >--movq $0x4,0x28(%rsp)
81090 44dfd3:>------00 00- 
81091 44dfd5:>------c3     >--retq---
lea 0x1ebd4(%rip),%rax得到char*, mov %rax,0x20(%rsp)復(fù)制給返回值, movq $0x4,0x28(%rsp)把長度也填進(jìn)去,

其實可以看到string就是c里面的char* 和len的組合

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • Golang中數(shù)據(jù)結(jié)構(gòu)Queue的實現(xiàn)方法詳解
  • 使用go實現(xiàn)常見的數(shù)據(jù)結(jié)構(gòu)
  • 淺析go中的map數(shù)據(jù)結(jié)構(gòu)字典
  • 淺談用Go構(gòu)建不可變的數(shù)據(jù)結(jié)構(gòu)的方法
  • golang數(shù)據(jù)結(jié)構(gòu)之golang稀疏數(shù)組sparsearray詳解

標(biāo)簽:海南 安康 西雙版納 遼寧 青海 物業(yè)服務(wù) 電子產(chǎn)品 儋州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Go語言模型:string的底層數(shù)據(jù)結(jié)構(gòu)與高效操作詳解》,本文關(guān)鍵詞  語言,模型,string,的,底層,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Go語言模型:string的底層數(shù)據(jù)結(jié)構(gòu)與高效操作詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于Go語言模型:string的底層數(shù)據(jù)結(jié)構(gòu)與高效操作詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    91蝌蚪精品视频| 韩国福利一区| 午夜精品电影| 久久精品视频16| 亚洲欧洲一区二区三区在线观看| 日韩av片永久免费网站| 久草视频免费在线观看| 亚洲精品欧美二区三区中文字幕| 成人台湾亚洲精品一区二区| a看欧美黄色女同性恋| 一区二区三区四区五区视频在线观看| 天堂av免费在线| 国产91沈先生在线播放| 欧美日韩一区二区三区在线观看免| 日韩夫妻性生活xx| 女人一区二区三区| 全部孕妇毛片丰满孕妇孕| 亚洲free性xxxx护士hd| 成人免费av片| 国产精品嫩草在线观看| 麻豆成人91精品二区三区| 成年免费网站| 日韩成人久久久| 中文字字幕在线中文乱码电影| 成人免费一区二区三区在线观看| 国产女同互慰高潮91漫画| 夜先锋资源站| 免费高清完整在线观看| 欧美精品 日韩| 久久精品一卡二卡| 99re6这里有精品热视频| 亚洲美女久久精品| 国产精品久久久久久福利| 91麻豆免费视频网站| 精品欧美一区二区久久久| 国产一级黄色av| 亚洲产国偷v产偷v自拍涩爱| 一色桃子久久精品亚洲| 米奇四色影视| 国产伦精品一区二区三区免费| 一本一本久久a久久综合精品蜜桃| eeuss第一页| 日韩一区二区av| 精品福利一区二区| 成人免费高清完整版在线观看| 亚洲免费成人在线| 国产三级小视频| 欧美一区二区视频免费观看| 黄色在线免费| 激情 小说 亚洲 图片: 伦| 国产精品亚洲一区二区三区在线观看| 亚洲经典中文字幕| 理论片一区二区在线| 91国内精品| 色一情一交一乱一区二区三区| 九九精品视频在线观看| 欧美多人爱爱视频网站| 国产精品久久久久77777| 美国黄色特级片| 99久久伊人精品影院| 最近2019年手机中文字幕| 日韩美女黄色片| 少妇一级淫免费播放| 麻豆一区在线观看| 国产一级精品视频| 91av入口| 国产精品一区二区在线观看| 欧美a级理论片| 乱精品一区字幕二区| 欧美区一区二区三区| a视频在线播放| 日本va欧美va瓶| 色婷婷激情综合| 欧美一区二区三区另类| 成人黄色大片在线观看| 免费观看特级毛片| 久久久久网站| 欧美日韩免费看| 精品久久久久久久免费人妻| 九色综合狠狠综合久久| 欧美国产在线观看| 又黄又爽在线免费观看| 日韩不卡高清| 日韩欧美国产一区二区三区| 成年人视频网站| 九九在线视频| 亚洲欧美综合v| 米奇精品一区二区三区在线观看| 久久影院电视剧免费观看| 精品久久一二三| wwwwww国产| 国产亚洲精品美女久久久久久久久久| 亚洲午夜久久久久久久| 国产不卡精品视男人的天堂| 国内在线视频| 日韩成人在线视频观看| 岳张嘴把我的精子吞下去| 欧美剧情电影在线观看完整版免费励志电影| 欧美日韩亚州综合| 蜜桃狠狠狠狠狠狠狠狠狠| 18视频免费网址在线观看| 国产精品自拍第一页| 欧美午夜电影在线观看| 国产影视一区二区| 69视频免费在线观看| 最好2018中文免费视频| 日韩免费小视频| 91成人小视频| 一区二区三区四区视频在线| 韩日精品一区二区| 亚洲韩国在线| 久久99精品久久久久| 欧洲美一区二区三区亚洲| 日韩理论在线观看| 亚洲狼人综合网| 国产成人无码av在线播放dvd| 欧美丰满片xxx777| 亚洲av激情无码专区在线播放| 日韩写真欧美这视频| 欧洲亚洲精品视频| 99理论电影网| 亚洲视频一二| 99久久免费精品国产免费| 欧美亚洲国产日本| 成年人看的羞羞网站| 欧美男人的天堂| 欧美日韩高清一区二区不卡| 91成人免费网站| 亚洲免费二区| 自拍偷拍 国产| 国产精品一二二区| 高清乱码毛片入口| 牛牛精品视频在线| 少妇av一区二区三区无码| 久久久久久网| 亚洲成人网在线观看| 2020最新国产精品| 少妇一级淫片免费看| 国产精品精华液网站| 精品日韩一区二区| 国产欧美自拍一区| 亚洲精品xxxxx| 波多野结衣网站| 精品电影一区二区| 亚洲人成网亚洲欧洲无码| 日本阿v视频在线观看| 亚洲一级免费观看| 超碰在线免费看| 日本五十路女优| 国产香蕉免费精品视频| 天天做日日爱夜夜爽| 亚洲精选在线观看| 日韩福利在线观看| 在线精品观看国产| 国产激情视频网址| 国产九区一区在线| 国产精品对白刺激久久久| 久草在线免费资源| 欧美福利一区| 国产麻豆视频免费观看| 亚洲青青久久| 久久亚洲国产成人| 欧美猛男做受videos| 青青草原国产在线观看| 亚州精品永久观看视频| 牛牛精品视频在线| 亚洲视频精品在线| 91久久精品国产91久久性色tv| 色94色欧美一区| 精品福利视频一区二区三区| 亚洲欧美日韩国产一区二区| 爱爱免费视频网站| 午夜亚洲性色福利视频| 日本免费在线视频观看| 精品自在线视频| 伊人av免费在线观看| 欧洲免费在线视频| 欧美办公室脚交xxxx| 国产精品一区二区三区在线免费观看| 大陆极品少妇内射aaaaaa| 欧美日韩综合网| 国产特级嫩嫩嫩bbb| 欧美色图影院| 国产精品日韩一区二区| 久久99国产精一区二区三区| 中日韩午夜理伦电影免费| 亚洲一区二区在线观| 最新中文字幕av| 色婷婷综合久久久中文字幕| xxxx黄色| 嫩草在线播放| 国产精品成人av| 日韩在线视频线视频免费网站| 亚洲在线播放电影| 亚洲网站啪啪| 青青草原成人网| 欧美午夜精品久久久| 在线观看中文字幕视频| 四虎永久免费影院| 天天摸日日摸狠狠添| 五月亚洲婷婷| 成人午夜看片网址| 亚洲成**性毛茸茸| 国产三级在线播放| 日本50路肥熟bbw| 亚洲乱码av中文一区二区| 国产视频一二三四区| 四虎影视1304t| 男女啪啪999亚洲精品| 亚洲第一导航| 99久久这里只有精品| 日产精品99久久久久久| 99鲁鲁精品一区二区三区| 精品国产免费人成电影在线观...| 亚洲欧美aaa| 一区二区自拍| 国产乱子伦精品无码码专区| 国产精品日日摸夜夜添夜夜av| 欧美1级2级| 99热成人精品热久久66| 大地资源网3页在线观看| 国内外成人免费视频| 一本一道波多野毛片中文在线| 欧美电影免费观看网站| 欧美日韩不卡合集视频| 天天色综合6| www.com毛片| 亚洲春色一区二区三区| 中文字幕jux大岛优香| 91麻豆蜜桃一区二区三区| 九九九九九精品| 亚洲免费看片| av片在线免费观看| 97精品超碰一区二区三区| 狠狠色丁香久久婷婷综合丁香| 激情综合自拍| 欧美一区二区三区免费| 国产午夜免费福利| 中文字幕一区二区三区人妻在线视频| 91丨九色丨蝌蚪丨老板| 性爽视频在线| 国产chinese精品一区二区| 99久久国产宗和精品1上映| 国产一二三四| 日韩av网站导航| 日韩精品国产一区二区| 蜜桃av噜噜一区二区三区麻豆| 欧美一区二区三区四区五区六区| 99精品视频在线免费播放| 五月婷婷狠狠操| 成人在线免费观看av| 亚洲综合视频网| 欧美性受xxxx黒人xyx性爽| 久久精品国产第一区二区三区最新章节| 高清av资源| 欧美xxxxx精品| 小鲜肉gaygays免费动漫| 久久精品一区二区免费播放| 色欲AV无码精品一区二区久久| 久久琪琪电影院| 国产又色又爽又黄刺激在线视频| 少妇aaaaa| 麻豆系列在线观看| 欧美午夜精品理论片a级按摩| 懂色av中文一区二区三区| 亚洲成人资源网| 亚洲第一色中文字幕| 国产成人精品片| 中文字幕欧美精品日韩中文字幕| 制服丝袜成人动漫| 成人免费网站在线观看视频| 久久99精品国产自在现线小黄鸭| 在线亚洲成人| 亚洲成人av福利| 在线heyzo| 欧美a在线视频| www.色在线| 久久精品成人| 亚洲尤物在线视频观看| 久久国产小视频| 免费观影入口看日本视频| 亚洲熟妇无码av| 国产欧美一区二区三区视频| a毛片不卡免费看片| 久久久久麻豆v国产精华液好用吗| 久久免费午夜影院| 亚洲精品永久视频| 天堂精品一区二区三区| 国产欧美一区二区三区小说| 欧美在线一级视频| 亚洲伊人一本大道中文字幕| 亚洲国产精品日韩专区av有中文| 亚洲经典在线| 毛片网站免费| 国产激情第一页| 国产成人精品999在线观看| 国产免费av网站| 在线视频亚洲欧美| 精品成人乱色一区二区| 久久久噜噜噜久噜久久| 黄动漫在线免费观看| 色欲av无码一区二区人妻| 午夜婷婷在线观看| 欧美激情小视频| 亚洲精品乱码久久久久久久| 久操视频在线观看| 在线成人国产| 日韩欧美一级| 天天靠夜夜靠| 四虎影成人精品a片| 亚洲一区二区免费视频| 国产精品人人妻人人爽人人牛| 亚洲精品成人久久| 日韩女优av电影在线观看| 欧美日韩视频精品二区| 欧美日韩精品二区| 国产精品日韩欧美综合| 免费黄网站在线播放| 欧美精品一区二区三区久久久| 99精品视频在线免费播放| 日本视频在线免费| 粉嫩av免费一区二区三区| 欧美无砖专区一中文字| 四季av日韩精品一区| 一级精品视频在线观看宜春院| 欧美特级黄色片| 26uuu色噜噜精品一区二区| 欧美福利一区二区|