Campbell Ritchie wrote:The Object#wait method with the two parameters does the same thing.
Makes sense. As far as I can tell, pretty much all these things ultimately rely on the host OS's equivalent of "sleep." Amazingly, there is much discussion about sleeping on the internet that reflects both a mix of ideas about how it works, and some persistent misconceptions.
At this point, here's what I (think I) know:
1. At one time, and, possibly, still today, Windows boots with a timer granularity of 1/64th of a second.
2. Any application can request a finer granularity, to the machine-specific limit, which is almost always 1/1000th of a second.
3. Damned near every machine ends up running at a timer granularity of 1/1000th of a second, maybe thanks to Chrome, maybe just because.
4. Any timer of whatever kind that purports to respect sub-millisecond accuracy is lying to you, unless it is spinning.
5. When your application sleeps, it probably means your CPU speed drops to your power plan's minimum, and it can take up to 40ms to come back up to full speed when your sleep unblocks.
Amazingly, this all means you can get better performance from an application by spinning instead of sleeping, because your spinning delays
can respect sub-millisecond accuracy (thus, you don't have to wait to the end of the next full millisecond to complete a delay you'd like to complete sooner), your spinning delays don't let the processor throttle down to a low CPU speed, and your spinning delays can be run either alternately on a
thread that doesn't spin when the delay is completed, or on a thread with lower priority than your actual working thread (which means it doesn't spin when that would compete with something useful).
In my tests, I was initially suprised to see that, when I used spinning, my CPU consumption was only 13%. You would think that, when spinning alternates with some other compute-bound activity, that would be 100%. But... my computer (a Dell XPS-8700) has eight cores. A single-threaded spin, alternating with compute-bound activity on the same thread, will completely consume one of those eight cores. What's one-eighth of 100%? Yup, it's 12.5%, about 13%, to the nearest whole number.
Thus, my entire set of problems (consistency, accuracy, latency) are solved by using a dumb, almost universally reviled technique: just loop until the counter says it's time to stop looping.
Who would have seen
that coming?