# Sleeping between 1e-2 and 1e-6s

**URL:** <https://www.ruby-forum.com/t/sleeping-between-1e-2-and-1e-6s/105923>\
**Category:** Ruby\
**Created:** [June 4, 2007, 5:57pm UTC](https://www.ruby-forum.com/t/sleeping-between-1e-2-and-1e-6s/105923 "2007-06-04T17:57:24Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![apeiros](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/838e76/32.png) [@apeiros](https://www.ruby-forum.com/u/apeiros)\
**Post date:** [June 4, 2007, 5:57pm UTC](https://www.ruby-forum.com/t/sleeping-between-1e-2-and-1e-6s/105923/1 "2007-06-04T17:57:24Z")

</div>

I noticed that ruby uses a different way to sleep with values \>1e-6s.  
I added my observations below. My question is now: what is the suggested  
way to sleep e.g. 0.001s?  
10000.times { sleep(0.0000001) }? Cant’ really be it, no? 🙂

The results:  
$ ruby sleeper.rb  
100x sleeping 0.01000000s: 0.01003044s per sleep, runtime: 1.00304s  
100x sleeping 0.00100000s: 0.01006163s per sleep, runtime: 1.00616s  
100x sleeping 0.00010000s: 0.01007538s per sleep, runtime: 1.00754s  
100x sleeping 0.00001000s: 0.01011209s per sleep, runtime: 1.01121s  
100x sleeping 0.00000100s: 0.01008325s per sleep, runtime: 1.00832s  
100x sleeping 0.00000010s: 0.00001131s per sleep, runtime: 0.00113s  
100x sleeping 0.00000001s: 0.00000986s per sleep, runtime: 0.00099s

The sleeper.rb file:  
#!/usr/bin/ruby

def bench(n=1, &b)  
start = Time.now  
n.to\_i.times(&b)  
Time.now-start  
end

[0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001].each {  
|s|  
r = bench(100) { sleep(s) }  
printf “100x sleeping %.8fs: %.8fs per sleep, runtime: %.5fs\n”, s,  
r/100, r  
}

Regards  
Stefan

---

<div class="post-metadata">

**Author:** ![apeiros](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/838e76/32.png) [@apeiros](https://www.ruby-forum.com/u/apeiros)\
**Post date:** [June 4, 2007, 9:16pm UTC](https://www.ruby-forum.com/t/sleeping-between-1e-2-and-1e-6s/105923/2 "2007-06-04T21:16:08Z")

</div>

On Tue, Jun 05, 2007 at 12:57:30AM +0900, Stefan R. wrote:

> I noticed that ruby uses a different way to sleep with values \>1e-6s.  
> I added my observations below. My question is now: what is the suggested  
> way to sleep e.g. 0.001s?  
> 10000.times { sleep(0.0000001) }? Cant’ really be it, no? 🙂

You’ve hit the granularity of the thread scheduler. On my machine,  
running  
your test code, it appears to be 4ms:

$ ruby sleep.rb  
100x sleeping 0.01000000s: 0.01210674s per sleep, runtime: 1.21067s  
100x sleeping 0.00100000s: 0.00407440s per sleep, runtime: 0.40744s  
100x sleeping 0.00010000s: 0.00411841s per sleep, runtime: 0.41184s  
100x sleeping 0.00001000s: 0.00411971s per sleep, runtime: 0.41197s  
100x sleeping 0.00000100s: 0.00000858s per sleep, runtime: 0.00086s  
100x sleeping 0.00000010s: 0.00000852s per sleep, runtime: 0.00085s  
100x sleeping 0.00000001s: 0.00000852s per sleep, runtime: 0.00085s

Ruby is not a precision real-time environment - and neither are Unix or  
Windows for that matter.

If you really need such a short pause, you could use ruby-inline and  
call  
nanosleep() or usleep() or select() C functions, depending on what’s  
available on your platform. You’ll block the entire Ruby interpreter for  
that period of time, i.e. Ruby won’t be able to do work in another  
thread at  
the same time, but at least the CPU will be available to other processes  
on  
your machine, unlike a spinloop as you propose above.

But you should think carefully about what you’re doing. For example, if  
you  
were trying to do

loop do  
send\_packet  
precision\_sleep(0.001)  
end

then you will certainly send less than 1000 packets per second, and the  
actual rate you send at will be variable. It may be better to send  
packets  
at an _average_ rate of 1000 packets per second, even if they go in  
bursts  
of 10 or 12 packets.

Brian.

---

<div class="post-metadata">

**Author:** ![apeiros](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/838e76/32.png) [@apeiros](https://www.ruby-forum.com/u/apeiros)\
**Post date:** [June 4, 2007, 10:03pm UTC](https://www.ruby-forum.com/t/sleeping-between-1e-2-and-1e-6s/105923/3 "2007-06-04T22:03:04Z")

</div>

Brian C. wrote:

> Ruby is not a precision real-time environment - and neither are Unix or  
> Windows for that matter.

Certainly not. But even with Ruby microsecond sleep should be possible.

> If you really need such a short pause, you could use ruby-inline and  
> call nanosleep() or usleep() or select() C functions

That would interrupt all threads. But it could still be an option for  
sleeps \< 0.01s. I.e. sleep everything \> 0.01s with thread\_wait\_for and  
switch to usleep for smaller values. Of course it would be nice to  
somehow get the granularity of the scheduler and switch at that.

> loop do  
> send\_packet  
> precision\_sleep(0.001)  
> end
> 
> then you will certainly send less than 1000 packets per second

The situation is indeed similar to the above. I’m also well aware of  
that problem. It’s not really an issue, though as I don’t sleep the  
interval but the time left in the interval (measured from an absolute  
start, not the last time the event happened).

After digging in the code I also understand what happens in that gap.  
timeval.tv\_usec is a long representing microseconds. Those values are  
rounded down to 0, so I assume it effectively doesn’t sleep.

Regards  
Stefan
