#Can someone explain why the slice is reduced in capacity?

39 messages · Page 1 of 1 (latest)

silver barn
lament sedge
#

the cap of the slice is 6

#

of which len is 4

#

if you remove the first two items

#

the cap still stays +2 of the length

#

since the end of the slice is unaffected

fallow onyx
# silver barn https://go.dev/tour/moretypes/11 In the Tour of Go.

First:

2, 3, 5, 7, 11, 13
^               ^
| data          | len, cap

Slice the slice to give it zero length.:

2, 3, 5, 7, 11, 13
^               ^
| data, len     | cap

Extend its length:

2, 3, 5, 7, 11, 13
^        ^      ^
| data   | len  | cap

Drop its first two values.:

2, 3, 5, 7, 11, 13
      ^  ^      ^
      |  | len  | cap
      | data
#

len and cap are counted from the data pointer (start of the array) if you advance the data pointer lan and cap has to shrink to compensate

#

also note you can't reslice a slice back on the left, only the right

#

here 2 and 3 are effectively lost (you would need to copy the slice before dropping the values to not have that happen)

#

note: my example used [x,y] ranging go uses [x,y) ranging

winter ether
fallow onyx
#

I don't know if this required by the language or implementation detail (because you could use unsafe to regain access FWIW)

silver barn
fallow onyx
#

it is hard and expensive to keep track of which individual indexes of array are still reachable it is also not cheap to resize allocations so the compiler and runtime just don't if anything points anywhere the whole array continues to exists

#

Also with [x,y) ranging:
First:

2, 3, 5, 7, 11, 13
^                 ^
| data            | len, cap

Slice the slice to give it zero length.:

2, 3, 5, 7, 11, 13
^                 ^
| data, len       | cap

Extend its length:

2, 3, 5, 7, 11, 13
^          ^      ^
| data     | len  | cap

Drop its first two values.:

2, 3, 5, 7, 11, 13
      ^    ^      ^
      |    | len  | cap
      | data

(this is actually how the slice works but is slightly more confusing when showed like this)

silver barn
#

What confuses me is that if you give it zero length you can still get it back the data when extend the length but if you drop the fist two you cannot get them back.

fallow onyx
#

you can access data to the right no problem

#

when you drop the first two you drop data on the left of the data pointer

#

which cannot be saved

silver barn
#

I need it to sink in

fallow onyx
#

@silver barn to do what you are suggesting you would something like this:

type slice struct{
 leftCapacity, leftLen uint
 data unsafe.Pointer
 rightLen, rightCapacity uint
}

Thoses are called butterfly pointers

silver barn
#

tour of go should mention this

fallow onyx
#

butterfly pointers ?

#

I don't think so

#

This would be more expensive because now each slice is 5 words instead of 3 and it would make bound checks more expensive too.
Note the current slice looks like this:

type slice struct{
 data unsafe.Pointer
 rightLen, rightCapacity uint
}

See how it's easier to check if an index is valid, I can just check i >= rightLen which is 1, maybe 2 instructions.

#

Having to check both left and right would make most [] operations slower, and that is an operation your programs should do a whole lot

silver barn
#

woah, Are you talking to me a bout butterfly pointers? that is way over my head at the moment

fallow onyx
#

I'm just saying, what you are asking is called "butterfly pointers", thoses are more expensive usually.
So go just do not use that, go because that is slightly faster and the only usecase needed in most applications it only keeps track of the right part of the slice

#

it just does not track things on the left

#

so if you discard them you can't get them back

#

also butterfly pointers are expensive and so this is a nice reason to have them in the language, go wants to be a simple language and butterfly pointers are not simple

silver barn
#

that is fine. but 'The Tour of Go' should mention that you loose elements on the left when slicing this way

fallow onyx
#

I think you are supposed to infer that yourself by looking at the output

#

you can submit a PR to make the tour better if you want

silver barn
#

I see. but I did not infer