Re: [go-nuts] Reset Slice with Make Every Time?

2017-01-10 Thread wadekim991 via golang-nuts


On Tue, 1/10/17, Marvin Renich <m...@renich.org> wrote:

 Subject: Re: [go-nuts] Reset Slice with Make Every Time?
 To: "golang-nuts" <golang-nuts@googlegroups.com>
 Date: Tuesday, January 10, 2017, 5:29 PM
 
 * Tomi Häsä <tomi.h...@gmail.com>
 [170110 02:23]:
 > On Tuesday, January 10,
 2017 at 1:49:37 AM UTC+2, kortschak wrote:
 > > On Mon, 2017-01-09 at 15:12 -0800,
 Tomi Häsä wrote: 
 > > > Is this
 the correct way of resetting a slice? I mean do I always
 > > > need to  use make to reset a
 slice? 
 > > > 
 >
 > >     // initialize slice 
 > > >     onearea Area =
 Area{} 
 > > >     group
 []Area = make( []Area, 0, MAX ) 
 > >
 > 
 > > >     // add
 stuff to slice 
 > > > 
    group = append( group, onearea ) 
 > > > 
 > >
 >     // reset slice 
 >
 > >     group = make( []Area, 0, MAX ) 
 > >
 > > group =
 group[:0] 
 > >
 >
 > > Using nil to reset a slice doesn't seem to be
 wise as the capacity
 > > > does not
 stay with MAX, but it will decrease to 2 in my program. 
 > > > 
 > >
 >     group = nil 
 > >
 > 
 > > > Full code here: https://github.com/tomihasa/unicodetest
 
 > 
 > By the way,
 what happens to the old data I used with the previous make
 
 > command?
 
 I'm not sure if these were mentioned
 earlier in the thread, but both
 https://blog.golang.org/slices and
 https://blog.golang.org/go-slices-usage-and-internals
 give some really
 good info on this.
 
 The abbreviated answer is to
 think of a slice as a view into its backing
 array.  As long as a slice (or other variable)
 refers to the backing
 array or one of its
 elements, the garbage collector will not reclaim any
 of the backing array.  So, even doing
     group = group[1:]
 will
 not allow the GC to reclaim the memory for the old
 group[0].
 
 If the elements
 of the slice (and therefore of the backing array) are
 simple values, such as ints, or structs of
 simple values, doing
     group =
 group[:0]
 will reset the slice to empty
 without changing its current capacity and
 without reallocating the memory for its backing
 array.
 
 If, however, the
 slice elements contain pointers, maps, channels, or
 other slices, then the memory referred to by
 those items will not be
 reclaimed, even
 though group appears to not refer to them.  As you
 append to group the second time around, those
 elements will be
 overwritten, and the memory
 referred to by the old values will be able
 to be reclaimed by the GC.  Example:
 
     type LargeStruct struct
 { /* lots of fields */ }
     func
 NewLargeStruct(i int) (ls *LargeStruct) { /* does what's
 needed */ }
     type SmallStruct struct {
 ls *LargeStruct }
     var small
 []SmallStruct = make([]SmallStruct, 0, 50)
     for i := 0; i < 10; i++ {
         small = append(small,
 SmallStruct{NewLargeStruct(i)})
     }
     small[:0]
 
 small is now an empty slice with capacity 50,
 but none of the memory
 allocated for the ten
 instances of LargeStruct is able to be reclaimed
 by the GC.  This is because the backing array
 still contains the
 pointers to all of the
 LargeStruct's allocated in the loop.  Now do
 
     small = append(small,
 SmallStruct{NewLargeStruct(41)})
     small
 = append(small, SmallStruct{NewLargeStruct(42)})
 
 and the memory allocated by
 NewLargeStruct(0) and NewLargeStruct(1) in
 the earlier loop can be reclaimed (assuming
 they are not referenced
 elsewhere).
 
 On the other hand,
 replacing
     small[:0]
 in
 the above code by
     small =
 make([]SmallStruct, 0, 50)
 will allocate a
 new backing array and will allow the old backing array
 as well as all of the LargeStruct's to be
 reclaimed.  Which is better
 will depend on
 your application.
 
 ...Marvin
 
 -- 
 You received this message because you are
 subscribed to the Google Groups "golang-nuts"
 group.
 To unsubscribe from this group and
 stop receiving emails from it, send an email to
 golang-nuts+unsubscr...@googlegroups.com.
 For more options, visit
 https://groups.google.com/d/optout.arlamentul de la Bucuresti a suspendat 
activitatea P.C.R.  care sustinuse fatis

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Reset Slice with Make Every Time?

2017-01-10 Thread Marvin Renich
* Tomi Häsä  [170110 02:23]:
> On Tuesday, January 10, 2017 at 1:49:37 AM UTC+2, kortschak wrote:
> > On Mon, 2017-01-09 at 15:12 -0800, Tomi Häsä wrote: 
> > > Is this the correct way of resetting a slice? I mean do I always
> > > need to  use make to reset a slice? 
> > > 
> > > // initialize slice 
> > > onearea Area = Area{} 
> > > group []Area = make( []Area, 0, MAX ) 
> > > 
> > > // add stuff to slice 
> > > group = append( group, onearea ) 
> > > 
> > > // reset slice 
> > > group = make( []Area, 0, MAX ) 
> >
> > group = group[:0] 
> >
> > > Using nil to reset a slice doesn't seem to be wise as the capacity
> > > does not stay with MAX, but it will decrease to 2 in my program. 
> > > 
> > > group = nil 
> > > 
> > > Full code here: https://github.com/tomihasa/unicodetest 
> 
> By the way, what happens to the old data I used with the previous make 
> command?

I'm not sure if these were mentioned earlier in the thread, but both
https://blog.golang.org/slices and
https://blog.golang.org/go-slices-usage-and-internals give some really
good info on this.

The abbreviated answer is to think of a slice as a view into its backing
array.  As long as a slice (or other variable) refers to the backing
array or one of its elements, the garbage collector will not reclaim any
of the backing array.  So, even doing
group = group[1:]
will not allow the GC to reclaim the memory for the old group[0].

If the elements of the slice (and therefore of the backing array) are
simple values, such as ints, or structs of simple values, doing
group = group[:0]
will reset the slice to empty without changing its current capacity and
without reallocating the memory for its backing array.

If, however, the slice elements contain pointers, maps, channels, or
other slices, then the memory referred to by those items will not be
reclaimed, even though group appears to not refer to them.  As you
append to group the second time around, those elements will be
overwritten, and the memory referred to by the old values will be able
to be reclaimed by the GC.  Example:

type LargeStruct struct { /* lots of fields */ }
func NewLargeStruct(i int) (ls *LargeStruct) { /* does what's needed */ }
type SmallStruct struct { ls *LargeStruct }
var small []SmallStruct = make([]SmallStruct, 0, 50)
for i := 0; i < 10; i++ {
small = append(small, SmallStruct{NewLargeStruct(i)})
}
small[:0]

small is now an empty slice with capacity 50, but none of the memory
allocated for the ten instances of LargeStruct is able to be reclaimed
by the GC.  This is because the backing array still contains the
pointers to all of the LargeStruct's allocated in the loop.  Now do

small = append(small, SmallStruct{NewLargeStruct(41)})
small = append(small, SmallStruct{NewLargeStruct(42)})

and the memory allocated by NewLargeStruct(0) and NewLargeStruct(1) in
the earlier loop can be reclaimed (assuming they are not referenced
elsewhere).

On the other hand, replacing
small[:0]
in the above code by
small = make([]SmallStruct, 0, 50)
will allocate a new backing array and will allow the old backing array
as well as all of the LargeStruct's to be reclaimed.  Which is better
will depend on your application.

...Marvin

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Reset Slice with Make Every Time?

2017-01-10 Thread djadala


On Tuesday, January 10, 2017 at 9:52:06 AM UTC+2, Chetan Gowda wrote:

Old data remains as it is in the existing allocation. It will be 
> overwritten as you fill up the slice again. 


This happens in case of group = group[:0],
OP asks what happens   in case of group = make( []Area, 0, MAX ),
In that case  old data will be garbage collected when GC runs.

Djadala  

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Reset Slice with Make Every Time?

2017-01-09 Thread Chetan Gowda
Old data remains as it is in the existing allocation. It will be overwritten as 
you fill up the slice again. 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Reset Slice with Make Every Time?

2017-01-09 Thread Tomi Häsä
By the way, what happens to the old data I used with the previous make 
command?

On Tuesday, January 10, 2017 at 1:49:37 AM UTC+2, kortschak wrote:
>
> On Mon, 2017-01-09 at 15:12 -0800, Tomi Häsä wrote: 
> > Is this the correct way of resetting a slice? I mean do I always need 
> > to  
> > use make to reset a slice? 
> > 
> > // initialize slice 
> > 
> > onearea Area = Area{} 
> > 
> > group []Area = make( []Area, 0, MAX ) 
> > 
> > // add stuff to slice 
> > 
> > group = append( group, onearea ) 
> > 
> > // reset slice 
> > 
> > group = make( []Area, 0, MAX ) 
>
>
> group = group[:0] 
>
>
> > Using nil to reset a slice doesn't seem to be wise as the capacity 
> > does not  
> > stay with MAX, but it will decrease to 2 in my program. 
> > 
> > group = nil 
> > 
> > Full code here: https://github.com/tomihasa/unicodetest 
> >  
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Reset Slice with Make Every Time?

2017-01-09 Thread Dan Kortschak
On Mon, 2017-01-09 at 15:12 -0800, Tomi Häsä wrote:
> Is this the correct way of resetting a slice? I mean do I always need
> to 
> use make to reset a slice?
> 
> // initialize slice
> 
> onearea Area = Area{}
> 
> group []Area = make( []Area, 0, MAX )
> 
> // add stuff to slice
> 
> group = append( group, onearea )
> 
> // reset slice
> 
> group = make( []Area, 0, MAX )


group = group[:0]


> Using nil to reset a slice doesn't seem to be wise as the capacity
> does not 
> stay with MAX, but it will decrease to 2 in my program.
> 
> group = nil
> 
> Full code here: https://github.com/tomihasa/unicodetest
> 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Reset Slice with Make Every Time?

2017-01-09 Thread Tomi Häsä
Is this the correct way of resetting a slice? I mean do I always need to 
use make to reset a slice?

// initialize slice

onearea Area = Area{}

group []Area = make( []Area, 0, MAX )

// add stuff to slice

group = append( group, onearea )

// reset slice

group = make( []Area, 0, MAX )

Using nil to reset a slice doesn't seem to be wise as the capacity does not 
stay with MAX, but it will decrease to 2 in my program.

group = nil

Full code here: https://github.com/tomihasa/unicodetest

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.