xxddpac
xxddpac

Reputation: 63

Confused about golang slice cap

i have a question about slice cap,the code:

var slice []int
list := []int{1,2,3,4,5}
for _,item := range list {
    slice = append(slice, item)
}
fmt.Println(len(slice),cap(slice))

if item == 1: len(slice)=1,cap(slice)=1

if item == 2: len(slice)=2,cap(slice)= 1*2

if item ==3: len(slice) = 3,cap(slice) = 2*2

if item == 4:len(slice) = 4,cap(slice) = 4

if item == 5:len(slice) = 5,cap(slice) = 4*2

so the output:

len(slice) = 5,cap(slice) = 8

that's no problem,but when i change the code:

var slice []int
slice = append(slice,1,2,3,4,5)
fmt.Println(len(slice),cap(slice))

output:

len(slice) = 5,cap(slice) = 6

why cap(slice) = 6 ?

Upvotes: 0

Views: 1418

Answers (1)

nipuna
nipuna

Reputation: 4095

You can see the algorithm of capacity calculation when appending in func growslice(et *_type, old slice, cap int) in src/runtime/slice.go - line 162

    newcap := old.cap
    doublecap := newcap + newcap
    if cap > doublecap {
        newcap = cap
    } else {
        if old.cap < 1024 {
            newcap = doublecap
        } else {
            // Check 0 < newcap to detect overflow
            // and prevent an infinite loop.
            for 0 < newcap && newcap < cap {
                newcap += newcap / 4
            }
            // Set newcap to the requested cap when
            // the newcap calculation overflowed.
            if newcap <= 0 {
                newcap = cap
            }
        }
    }
  • First multiply the old slice capacity by 2. If the capacity after multiplying by 2 is still less than the new slice capacity, then take the new slice capacity (append multiple elems)
  • If the new slice is less than twice the old slice capacity, multiply the old slice capacity by 2
  • If the old slice capacity is greater than or equal to 1024, the new slice capacity is multiplied by the old slice capacity by 1.25

Reference -

Upvotes: 6

Related Questions