golang 切片擴(kuò)容的探討
分以下幾種情況:
1.切片每次新增個(gè)數(shù)不超過原來的1倍峡蟋,且每次增加數(shù)不超過1024個(gè),且增加后總長(zhǎng)度小于1024個(gè)赎婚,這種情況下擴(kuò)容后為原來的2倍
s1 := make([]int, 0)
fmt.Printf("The capacity of s1: %d\n", cap(s1))
for i := 1; i <= 17; i++ {
s1 = append(s1, i)
fmt.Printf("s1(%d): len: %d, cap: %d\n", i, len(s1), cap(s1))
}
fmt.Println()
結(jié)果:
/*
The capacity of s1: 0
s1(1): len: 1, cap: 1
s1(2): len: 2, cap: 2
s1(3): len: 3, cap: 4
s1(4): len: 4, cap: 4
s1(5): len: 5, cap: 8
s1(6): len: 6, cap: 8
s1(7): len: 7, cap: 8
s1(8): len: 8, cap: 8
s1(9): len: 9, cap: 16
s1(10): len: 10, cap: 16
s1(11): len: 11, cap: 16
s1(12): len: 12, cap: 16
s1(13): len: 13, cap: 16
s1(14): len: 14, cap: 16
s1(15): len: 15, cap: 16
s1(16): len: 16, cap: 16
s1(17): len: 17, cap: 32
*/
2.切片一次新增個(gè)數(shù)超過原來1倍逊彭,但不超過1024個(gè)瓦戚,且增加后總長(zhǎng)度小于1024個(gè)团驱,這種情況下擴(kuò)容后比實(shí)際具有的總長(zhǎng)度還要大一些摸吠。
s2 := make([]int, 10)
fmt.Printf("The capacity of s2: %d\n", cap(s2))
r1 := append(s2, make([]int, 5)...)
fmt.Printf("r1: len: %d, cap: %d\n", len(r1), cap(r1))
r2 := append(s2, make([]int, 11)...)
fmt.Printf("r2: len: %d, cap: %d\n", len(r2), cap(r2))
r3 := append(s2, make([]int, 21)...)
fmt.Printf("r3: len: %d, cap: %d\n", len(r3), cap(r3))
fmt.Printf("注意:像r2,r3 一次增加個(gè)數(shù)超過原容量的1倍,增加后結(jié)果比實(shí)際總長(zhǎng)度預(yù)想的稍大一點(diǎn) \n")
fmt.Println()
結(jié)果:
/*
The capacity of s2: 10
r1: len: 15, cap: 20
r2: len: 21, cap: 22
r3: len: 31, cap: 32
注意:像r2,r3 一次增加個(gè)數(shù)超過原容量的1倍嚎花,增加后結(jié)果比實(shí)際總長(zhǎng)度預(yù)想的稍大一點(diǎn)
*/
3.原切片長(zhǎng)度超過1024時(shí)寸痢,一次增加容量不是2倍而是0.25倍,每次超過預(yù)定的都是0.25累乘
// 1024 * 0.25 = 256
s3 := make([]int, 1024)
fmt.Printf("The capacity of s3: %d\n", cap(s3))
r4 := append(s3, make([]int, 200)...)
fmt.Printf("r4: len: %d, cap: %d\n", len(r4), cap(r4))
r5 := append(s3, make([]int, 256)...)
fmt.Printf("r5: len: %d, cap: %d\n", len(r5), cap(r5))
// 1280 * 0.25 = 320
r6 := append(s3, make([]int, 266)...)
fmt.Printf("r6: len: %d, cap: %d\n", len(r6), cap(r6))
fmt.Printf("注意:像r6 一次增加個(gè)數(shù)超過原容量的0.25倍紊选,增加后結(jié)果比原容量1.25倍預(yù)想的稍大一點(diǎn) \n")
fmt.Println()
結(jié)果:
/*
The capacity of s3: 1024
r4: len: 1224, cap: 1280
r5: len: 1280, cap: 1280
r6: len: 1290, cap: 1696
注意:像r6 一次增加個(gè)數(shù)超過原容量的0.25倍啼止,增加后結(jié)果比原容量1.25倍預(yù)想的稍大一點(diǎn)
*/
說明下:第三種情況,又分為兩種丛楚,一種是原長(zhǎng)度不小于1024時(shí)族壳,一次擴(kuò)容后為原來的1.25倍(當(dāng)然一次增加的個(gè)數(shù)不超過原長(zhǎng)度的0.25倍)憔辫;第二種情況就是一次增加個(gè)數(shù)超過原長(zhǎng)度的0.25倍趣些,擴(kuò)容后其容量比預(yù)想的總長(zhǎng)度稍大點(diǎn),就比如 r6: len: 1290, cap: 1696, 一次擴(kuò)容長(zhǎng)度大于0.25倍贰您,擴(kuò)容后坏平,其實(shí)際容量比0.25累乘預(yù)想的大一點(diǎn),比如10241.251.25 = 1600 锦亦,實(shí)際為1696.
示例代碼保存在GitHub地址:點(diǎn)擊