Home > OS >  Go: Unexpected Results from time.Sleep
Go: Unexpected Results from time.Sleep

Time:08-18

Running this code (as a built executable, not with the debugger):

package main

import (
    "fmt"
    "time"
)

func main() {
    startTime := time.Now()
    for i := 0; i < 1000; i   {
        time.Sleep(1 * time.Millisecond)
    }
    fmt.Printf("%d\n", time.Since(startTime).Milliseconds())
}

I get the output:

15467

This seems like a major overhead for calling the time.Sleep() function; it's essentially taking 15ms per loop iteration, even though it's only sleeping for 1ms in each loop. This suggests that there's a 14ms overhead for running an iteration of the loop and initiating a sleep.

If we adjust the sleep duration:

package main

import (
    "fmt"
    "time"
)

func main() {
    startTime := time.Now()
    for i := 0; i < 1000; i   {
        time.Sleep(10 * time.Millisecond)
    }
    fmt.Printf("%d\n", time.Since(startTime).Milliseconds())
}

I get the output:

15611

This is essentially the same duration, even though it should be sleeping for 10x as long. This kills the idea that there's a 14ms overhead for the loop iteration and initiating the sleep, because if that were the case, it would be (14 10)*1000 = 24000ms total, which it is not.

What am I missing? Why would this code take the same duration to execute, whether the sleep duration is 1ms or 10ms?

Note that I've tried running this in the Go playground but get different results; I think it handles sleeping differently. These results are consistent on my laptop, which is running an i7-10510.

CodePudding user response:

It is probably related to the frequency of the system's timer. For example, on Windows the clock ticks every 15 milliseconds (source):

For example, for Windows running on an x86 processor, the default interval between system clock ticks is typically about 15 milliseconds, and the minimum interval between system clock ticks is about 1 millisecond. Thus, the expiration time of a default-resolution timer (which ExAllocateTimer creates if the EX_TIMER_HIGH_RESOLUTION flag is not set) can be controlled only to within about 15 milliseconds, but the expiration time of a high-resolution timer can be controlled to within a millisecond.

If you need a higher precision timer you probably need to find a way to use High-Resolution Timers.

More information can be found in the threads below:

  • Related