allocation - Can (the underlying array of) a slice with large starting index in Go be allocated memory-efficiently? -


i'm trying use slice, myslice, large starting index. rather explicitly subtracting starting index using myslice[index - myslicestartindex], tempted define slice in such way can use without such arithmetic myslice[index]. can done without allocating memory unused low indices?

the naive way of doing this, allocating slice , reslicing (e.g. myslice = myslice[3*1024*1024*1024:4*1024*1024*1024]) is memory inefficient because underlying array not needs allocated entire range, remains allocated. not work, because afterwards data formerly @ index 3*1024*1024*1024 @ index 0, whilst goal keep @ original index.

can allocate slice (or underlying array) in such way indices below slice's start not allocated, ideally not initially?

this not possible without /not/ allocating unused parts. way slice defined in go, through reflect.sliceheader

type sliceheader struct {     data uintptr     len  int     cap  int } 

it contains no starting index field. merely reference underlying, fixed size array. underlying array holds actual data. slice 'window' array, begins @ index 0. wherever 0 may in underlying array.

for instance, consider following code:

a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} b := a[2:8] c := a[8:] d := b[2:4] 

this yields memory layout follows:

fixed array: [ 0 1 2 3 4 5 6 7 8 9 ]  > [10]int @ address 273785072 slice    :   . . . . . . . . . .    > sliceheader{data:273785072 len:10 cap:10} slice b    :       . . . . . .        > sliceheader{data:273785080 len:6 cap:8} slice c    :                   . .    > sliceheader{data:273785104 len:2 cap:2} slice d    :           . .            > sliceheader{data:273785088 len:2 cap:6} 

the values data address offsets fixed array , 4 slices share underlying storage.

a =:= $273785072 b =:= $273785080 =:= $a + sizeof(int)*2 =:= $a + 8 c =:= $273785104 =:= $a + sizeof(int)*8 =:= $a + 32 d =:= $273785088 =:= $b + sizeof(int)*2 =:= $a + sizeof(int)*4 =:= $a + 16 

at whatever index re-slice existing slice, new slice indexed 0 len(s), because address in underlying fixed array points puts there.

memory mapping

if data loaded file on disk, can have different option: use syscall.mmap provide access data through slice, starting @ desired index. returned slice index 0 , covers range specified.

func mmap(fd *os.file, start, size int) ([]byte, error) {     _, err := fd.seek(0, 0)     if err != nil {         return nil, err     }      return syscall.mmap(int(fd.fd()), start, size,         syscall.prot_read, syscall.map_shared) } 

do not forget call syscall.munmap on returned slice, when done using it.


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -