Hello all,
I’m pretty new to Go, just started learning it 6 weeks ago. I’m coming from using Python for the last 3 years, and am 100% self-taught (my ADHD makes it exceptionally hard to take formal classes or read a book cover to cover.
Anyways, I am building my first Go project for work and have come across what may be a fairly trivial issue, but I haven’t been able to find a post on this specific question.
When ranging over a slice of structs, is it more efficient to range over the element or the index?
To start, here are my project requirements and the approach I’m taking:
I work for a nationwide retailer and am building a script that puts stores in like groups, based on the last full quarter of sales data. Comparing total sale volume, top items sold, source warehouse and relative location.
To do this, I have built a series of structs and typed slices of those structs. (I’ve redacted some of the code due to company IP rules)
Below is some of my code along with two functions that demonstrate the two approaches.
In addition to thoughts on which approach is more memory efficient, any general feedback on my code would also be greatly appreciated! I’m too far in to this project to make significant changes, but I will definitely take note for application in future projects.
type storeMaster struct {
store int
location storeLocation
department storeDepartment
}
type storeLocation struct {
warehouse int
postal int
}
type storeDepartment struct {
department int //department id (for grouping stores at a department level)
weeks int //count of weeks with active sales
retail float64 // $$
avgRetail float64 // $$ retail / float64(weeks)
lastWeek int //most recent week with sales
items storeItemSlice
}
type storeItem struct {
upc int64
weeks int //count of weeks with active sales for item
retail float64 // $$
avgRetail float64 // $$ retail / float64(weeks)
lastWeek int //most recent week with sales for item
}
type storeMasterSlice []storeMaster
type storeItemSlice []storeItem
func (u storeItemSlice) Len() int { return len(u) }
func (u storeItemSlice) Less(i, j int) bool { return u[i].avgRetail > u[j].avgRetail }
func (u storeItemSlice) Swap(i, j int) { u[i], u[j] = u[j], u[i] }
func (u storeItemSlice) Sort() { sort.Sort(u) }
// function that ranges over the elements
func (m *storeMaster) topItems() (top10, top25, top50 []int64) {
var items storeItemSlice
weeks, lastWeek := (*m).maxWeek()
weeks = int(math.Round(float64(weeks) * .75))
lastWeek = lastWeek - 3
for _, item := range (*m).department.items {
if item.weeks >= weeks && item.lastWeek >= lastWeek {
items = append(items, item)
}
}
items.Sort()
for i := 0; i < 50; i++ {
top50 = append(top50, items[i].upc)
}
top25 = top50[:25]
top10 = top50[:10]
return top10, top25, top50
}
// function that ranges over the index
func (m *storeMaster) maxWeek() (weeks, lastWeek int) {
for i := range (*m).department.items {
if (*m).department.items[i].weeks > weeks {
weeks = *m.department.items[i].weeks
}
if (*m).department.items[i].lastWeek > lastWeek {
lastWeek = (*m).department.items[i].lastWeek
}
}
return weeks, lastWeek
}
Thank you in advance for any feedback you can give me!