How expensive is a new timer?

265 views
Skip to first unread message

Jakob Borg

unread,
May 27, 2014, 7:19:30 AM5/27/14
to golang-nuts
I have code with a select loop consuming values from a number of
channels, that I need to time out. The channels aren't *done* sending
data forever (so they won't be closed etc) but they are done for about
a minute or so and I need to do some cleanup on the work that has been
done in the meantime. While there is work, the loop is spinning at a
couple thousand revolutions per second... It's similar to the
following:

for {
select {
case v := <-c1:
// do something with this value
case v := <-c2:
// do something with this value
case <-time.After(5 * time.Second):
break
}
}

Actually, right now it's actually more like the following;

timeout := time.Tick(5 * time.Second)
for {
select {
case v := <-c1:
// do something with this value
case v := <-c2:
// do something with this value
case <-timeout:
// bunch of nasty code to figure out if we are "done" or
if we should continue the loop
}
}

The reason for the second variant is that I was nervous that spawning
thousands of timers per second that I'm not interested in, only to
have them be garbage collected at some later time would be crappy. I
was imagining the naive timer implementation (a goroutine with a sleep
and a send, basically). However I see the timer implementation is a
bit more sophisticated than that.

So is the first loop a good use of time.After, or is the resource
usage going to bite me?

//jb

Ian Lance Taylor

unread,
May 27, 2014, 9:15:39 AM5/27/14
to Jakob Borg, golang-nuts
A new timer is not expensive but it is not free. You can make it
cheaper by doing something like

timer := time.NewTimer(5 * time.Second)
select {
case v := <-c1:
// do something with this value
timer.Reset(5 * time.Second)
case v := <-c2:
// do something with this value
timer.Reset(5 * time.Second)
case <-timer.C
// Nothing has happened for 5 seconds.
break
}

Ian
Reply all
Reply to author
Forward
0 new messages