欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解golang的切片擴(kuò)容機(jī)制

 更新時間:2023年07月17日 08:43:25   作者:小小的蒟蒻  
golang的切片擴(kuò)容機(jī)制是golang面試者繞不開的一扇大門,無論在面試提問,或者面試情景上都繞不開它,今天就說說我理解下的切片擴(kuò)容機(jī)制,感興趣的小伙伴跟著小編一起來看看吧

前言

golang的擴(kuò)容機(jī)制:在go1.18之前有一個臨界值為1024,小于1024的時候,切片先兩倍擴(kuò)容,如果兩倍擴(kuò)容后的容量還是不夠,就直接以切片需要的容量作為容量。

在go1.18之后,臨界值換成了256,小于256和前面相同,大于256公式變?yōu)椋╫ldcap+3*256)/4這個公式的值隨著oldcap的越來越大,從2一直接近1.25,相對于1.18之前可以更平滑的過渡。

上面就是切片擴(kuò)容的基本規(guī)則機(jī)制,但還有一個小的規(guī)則,下面就來看看

發(fā)現(xiàn)問題

看下面一行代碼

運(yùn)行結(jié)果如下

出現(xiàn)上面的結(jié)果原因是,剛開始切片容量為1,兩倍擴(kuò)容之后,變?yōu)?,但是2不夠,所以變?yōu)樗枰娜萘?,后面在加4個數(shù)字,繼續(xù)擴(kuò)容,2倍之后是6,但是6不夠應(yīng)該變?yōu)樾枰娜萘浚瑧?yīng)該為7,為什么是8呢

解決問題

先貼一下源代碼,下面第一段代碼是擴(kuò)容機(jī)制的基礎(chǔ)代碼(1.18之前)

下面是造成上面原因的代碼

下面是1.18之后的基礎(chǔ)擴(kuò)容機(jī)制

從上面代碼分析之后,造成7變成8的原因就在這個roundupsize函數(shù)上面,它有一個計算公式

capmem = roundupsize(uintptr(newcap) * ptrSize)
newcap = int(capmem / ptrSize)

其中 ptrSize 在 64 位機(jī)器下的大小為 8。 而此時 newcap 的值為 7,所以傳入到 roundupsize 函數(shù)內(nèi)部的值為 7 * 8 = 56 。接著看看 roundupsize 的內(nèi)部:

func roundupsize(size uintptr) uintptr {
	if size < _MaxSmallSize {
		if size <= smallSizeMax-8 {
			return uintptr(class_to_size[size_to_class8[(size+smallSizeDiv-1)/smallSizeDiv]])
		} else {
			//……
		}
	}
    //……
}
const _MaxSmallSize = 32768
const smallSizeMax = 1024
const smallSizeDiv = 8
var size_to_class8 = [smallSizeMax/smallSizeDiv + 1]uint8{0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31}
var class_to_size = [_NumSizeClasses]uint16{0, 8, 16,,24,32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024, 1152, 1280, 1408, 1536, 1792, 2048, 2304, 2688, 3072, 3200, 3456, 4096, 4864, 5376, 6144, 6528, 6784, 6912, 8192, 9472, 9728, 10240, 10880, 12288, 13568, 14336, 16384, 18432, 19072, 20480, 21760, 24576, 27264, 28672, 32768}

roundupsize 的返回值為 uintptr(class_to_size[size_to_class8[(size+smallSizeDiv-1)/smallSizeDiv]]),而:

  • (size+smallSizeDiv-1)/smallSizeDiv = (56 + 8 - 1) / 8 = 7
  • size_to_class8[7] = 5
  • class_to_size[5] = 64 所以 roundopsize 的返回值為 64 ,newcap = int(capmem / ptrSize) = int(64 / 8) = 8 ,所以最終原切片的容量擴(kuò)充到了 8。

總結(jié)

如果以后遭遇情景題我們按照這個公式算的話很費(fèi)時間,所以我總結(jié)了一下規(guī)則,就是如果遇見2倍擴(kuò)容之后不夠需要直接用它所需要的容量的情況,如果是1和3,它的容量可以是1和3,但如果是5,7,9,11等其他的奇數(shù),全部取+1得到離他最近的偶數(shù),因?yàn)檫@個值與class_to_size有關(guān),class_to_size全部存的是8的倍數(shù),把class_to_size里面的值全部除以8,結(jié)果為:0,1,2,3,4,6,8,10...........和咱們的規(guī)律非常吻合

到此這篇關(guān)于詳解golang的切片擴(kuò)容機(jī)制的文章就介紹到這了,更多相關(guān)golang切片擴(kuò)容機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 用gin開發(fā)的golang項(xiàng)目三種開發(fā)模式方式

    用gin開發(fā)的golang項(xiàng)目三種開發(fā)模式方式

    這篇文章主要介紹了用gin開發(fā)的golang項(xiàng)目三種開發(fā)模式方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • golang利用redis和gin實(shí)現(xiàn)保存登錄狀態(tài)校驗(yàn)登錄功能

    golang利用redis和gin實(shí)現(xiàn)保存登錄狀態(tài)校驗(yàn)登錄功能

    這篇文章主要介紹了golang利用redis和gin實(shí)現(xiàn)保存登錄狀態(tài)校驗(yàn)登錄功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • Go?數(shù)據(jù)結(jié)構(gòu)之二叉樹詳情

    Go?數(shù)據(jù)結(jié)構(gòu)之二叉樹詳情

    這篇文章主要介紹了?Go?數(shù)據(jù)結(jié)構(gòu)之二叉樹詳情,二叉樹是一種數(shù)據(jù)結(jié)構(gòu),在每個節(jié)點(diǎn)下面最多存在兩個其他節(jié)點(diǎn)。即一個節(jié)點(diǎn)要么連接至一個、兩個節(jié)點(diǎn)或不連接其他節(jié)點(diǎn),下文基于GO語言展開二叉樹結(jié)構(gòu)詳情,需要的朋友可以參考一下
    2022-05-05
  • golang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go+Redis緩存設(shè)計與優(yōu)化實(shí)現(xiàn)

    Go+Redis緩存設(shè)計與優(yōu)化實(shí)現(xiàn)

    本文主要介紹了Go+Redis緩存設(shè)計與優(yōu)化實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • 從源碼解析golang Timer定時器體系

    從源碼解析golang Timer定時器體系

    本文詳細(xì)介紹了Go語言中的Timer和Ticker的使用方式、錯誤使用方式以及底層源碼實(shí)現(xiàn),Timer是一次性的定時器,而Ticker是循環(huán)定時器,正確使用時需要注意返回的channel和垃圾回收問題,Go 1.23版本對定時器進(jìn)行了改進(jìn),優(yōu)化了垃圾回收和停止、重置相關(guān)方法
    2025-01-01
  • 深入探討Golang中如何進(jìn)行并發(fā)發(fā)送HTTP請求

    深入探討Golang中如何進(jìn)行并發(fā)發(fā)送HTTP請求

    在?Golang?領(lǐng)域,并發(fā)發(fā)送?HTTP?請求是優(yōu)化?Web?應(yīng)用程序的一項(xiàng)重要技能,本文探討了實(shí)現(xiàn)此目的的各種方法,文中的示例代碼講解詳細(xì),希望對大家有所幫助
    2024-01-01
  • go?語言爬蟲庫goquery的具體使用

    go?語言爬蟲庫goquery的具體使用

    GoQuery是專為Go語言設(shè)計的一個強(qiáng)大的HTML解析和查詢庫,本文主要介紹了go語言爬蟲庫goquery的具體使用,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • golang多次讀取http request body的問題分析

    golang多次讀取http request body的問題分析

    這篇文章主要給大家分析了golang多次讀取http request body的問題,文中通過代碼示例和圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • Golang?Time包與日期函數(shù)的用法詳解

    Golang?Time包與日期函數(shù)的用法詳解

    在golang中,time包提供了時間的顯示和測量用的函數(shù),下面小編就來和大家詳細(xì)聊聊Golang中Time包與日期函數(shù)的具體用法,快跟隨小編一起學(xué)習(xí)一下吧
    2023-07-07

最新評論