Up to Main Index Up to Journal for July, 2012 JOURNAL FOR MONDAY 9TH JULY, 2012 ______________________________________________________________________________ SUBJECT: I feel a disturbance in my code... DATE: Mon Jul 9 22:02:49 BST 2012 Didn't get much time for coding this weekend, however I did manage to watch some more Google I/O 2012 videos and catchup with the golang go nuts mailing list[1]. Ever since then I had an uneasy feeling that something wasn't quite as it should be with the code for my prototype. This evening I made some experimental changes and had a nice surprise! When composing object via embedding I was using something like: type Item struct { *thing.Thing weight units.Weight } This involves two structs - one for Item and a pointer to a Thing struct. Everything works as expected and there is nothing wrong with it. But! It looks like there is a better way to do this: type Item struct { thing.Thing weight units.Weight } A simple change - Thing is now embedded directly into Item without a pointer and we only have a single struct. This may not seem that important. However we now have just one struct instead of two tied together via a pointer. This lowers memory usage AND seems to make the garbage collector much happier. All of the debugging using finalizers and explicit setting of pointers to nil etc has all just gone away. So I've modified all of the structs and am currently running tests on the modified code. However I think I can still do better. Each 'thing' is created using a New() function. For example Thing and Item have: func New(name string, aliases []string, description string) *Thing { t := &Thing{ name: name, aliases: make([]string, len(aliases)), description: description, uniqueId: <-Next, mutex: make(chan bool, 1), } for i, a := range aliases { t.aliases[i] = strings.ToUpper(strings.TrimSpace(a)) } log.Printf("Thing %d created: %s\n", t.uniqueId, t.name) return t } New(name string, aliases []string, description string, weight units.Weight) *Item { return &Item{ Thing: *thing.New(name, aliases, description), weight: weight, } } What happens here is that Thing is Embedded into Item. To do so Item calls thing.New() to create a new *Thing the embedding then seems to create a copy[2] of the Thing referenced and the Thing is then finalised because it's no longer referenced! So instead of returning a reference to the new Thing I could possibly allocate the data directly into the Item and save another object creation - which also saves on allocation and garbage collection. Is this was made the garbage collector happier? So a little more investigating to do but it all looks good to me ;) -- Diddymus [1] Go users mailing list: https://groups.google.com/group/golang-nuts [2] I think the copy is done for the allocation into the Item struct? Up to Main Index Up to Journal for July, 2012