1

I want to create a pointer and use it in every iteration but in the and I get all the same values. So I found the solution using creating the pointer in every iteration. But this approach seems wasting a lot of memory.

Is there a way to reuse the same variable in Go?

Here is my code

func GetSchedules(start, end time.Time, usr *user.User) ([]*Scheduler, error) {
    queryStr := []string{"SELECT account_id,link,text,time,image_links from", Table, "where user_id=?"}
    var results = make([]*Scheduler, 0)
    rows, err := DB.MYSQL_DB.Query(strings.Join(queryStr, " "), usr.Id.Hex())
    if nil != err {
        return results, err
    }
    defer rows.Close()
    a := new(Scheduler)
    for rows.Next() {
        
        cols := []interface{}{&a.AccountId, &a.Link, &a.Text, &a.Time, &a.Images}
        fmt.Println(rows.Scan(cols...))
        results = append(results, a)

    }

    return results, nil
}

hereThe problem is with the variable called a although I am scanning new stuff into it in every iteration it just keeps showing the last one and the results slice contains just the last item multiple times

5
  • The above code should give you different values, since you allocate a in every iteration. So which one is the problem? Commented Jun 23, 2017 at 12:19
  • yes it does but i dont want to allocate everytime because if i allocate everytime it means i need to free everytime and this cant be done in go and so gc will interfere more @putu Commented Jun 23, 2017 at 12:35
  • i just updated code to the one that doesnt work so it wont be confusing any more Commented Jun 23, 2017 at 12:37
  • 1
    You can't create 1 value, and somehow have that be multiple different values. Create the values you need, and don't worry about GC. If GC is a problem for some reason, make an example showing that particular problem. Commented Jun 23, 2017 at 12:40
  • @JimB the point is that i have created a single variable but i am updating it inside the array and just there i am appending that i wanna append the value not a reference to the actual variable and while writing this comment i just understood what to do thank you :) Commented Jun 23, 2017 at 13:12

1 Answer 1

4

Don't worry about GC until you have proof that it is a bottleneck in your application. When reading data from DB, GC will never be a bottleneck for you. This is a simple benchmark:

func BenchmarkReallocate(b *testing.B) {
    for i := 0; i < b.N; i++ {
        results := make([]*foo, 0)
        for i := 0; i < 100; i++ {
            f := new(foo)
            f.bar = "baz"
            results = append(results, f)
        }
    }
}

func BenchmarkReuse(b *testing.B) {
    for i := 0; i < b.N; i++ {
        results := make([]*foo, 0)
        var f *foo
        for i := 0; i < 100; i++ {
            f = new(foo)
            f.bar = "baz"
            results = append(results, f)
        }
    }
}

Results of running go test -bench . -benchmem:

BenchmarkReallocate-8         300000          4416 ns/op        3640 B/op        108 allocs/op
BenchmarkReuse-8              300000          4359 ns/op        3640 B/op        108 allocs/op
PASS

So in the end both ways result in exactly the same amount of allocations.

And the typical reading from DB into struct looks like this:

rows, err := db.Query("SELECT * FROM foo")
if nil != err {
    return nil, err
}
defer rows.Close()
results := make([]*Scheduler, 0)
for rows.Next() {
    var s Scheduler
    if err := rows.Scan(&s.Id, &s.Name, &s.Something); err != nil {
        return nil, err
    }
    results = append(results, &s)
}
if err := rows.Err(); err != nil { // Don't forget to check rows.Err()
    return nil, err
}
return results, nil
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.