calculating system clock resolution

J

jUrner

Hello all

I have the problem of how to calculate the resolution of the system
clock.
Its now two days of head sratching and still there is nothing more than
these few lines on my huge white sheet of paper stiring at me. Lame I
know.

import time

t1 = time.time()
while True:
t2 = time.time()
if t2 > t1:
print t1, t2
# start calculating here
break


BTW t1 and t2 print out equal up to the fraction on my machine. What
does
python know that I don't? A pointer to the source lines where this is
implemented
would even be helpfull to clear this out. Can't seem to find it.

Anyone any ideas?
 
M

MrJean1

Depends .... iff you are using Linux, print

cat /proc/cpuinfo

and look for the line "cpu ...Hz: ...". Parsing that would be
straightforward.

Keep in mind, the time.time() function reports the "wall clock" time,
which usually has up to a millisecond resolution, regardless of the CPU
speed.

There is also time.clock(), more about that on
<http://docs.python.org/lib/module-time.html>

/Jean Brouwers
 
S

Serge Orlov

Hello all

I have the problem of how to calculate the resolution of the system
clock.
Its now two days of head sratching and still there is nothing more than
these few lines on my huge white sheet of paper stiring at me. Lame I
know.

import time

t1 = time.time()
while True:
t2 = time.time()
if t2 > t1:
print t1, t2
# start calculating here
break


BTW t1 and t2 print out equal up to the fraction on my machine. What
does
python know that I don't? A pointer to the source lines where this is
implemented
would even be helpfull to clear this out. Can't seem to find it.

Anyone any ideas?

I think you are pretty close:

import time

def resolution_sample():
t1 = time.time()
while True:
t2 = time.time()
if t2 > t1:
return t2 - t1

def timer_resolution():
return min(resolution_sample() for x in xrange(10))

The function above (timer_resolution) is actually pretty dumb. I think
the number of samples to take depends on resolution.
 
J

jUrner

Maybe it was not too clear what I was trying to point out.

I have to calculate the time time.time() requires to return the next
tick of the clock.
Should be about 0.01ms but this may differ from os to os.

BTW (I'm new to linux) cat /proc/cpuinfo is nice but I have 2457.60
bogomips.
Is this something i should be concerned about? I mean is this
contageous or something ;-)
 
S

Steven D'Aprano

Maybe it was not too clear what I was trying to point out.

I have to calculate the time time.time() requires to return the next
tick of the clock.
Should be about 0.01ms but this may differ from os to os.

I suspect that Python isn't quite fast enough to give an accurate measure
for this, but I could be wrong.

You can try this:

def calc_time_res():
now = time.time
start = now()
x = start
while start == x:
x = now()
print x - start

Trying it, I get a fairly small number:



Traceback (most recent call last):
File "<stdin>", line 1, in ?
 
S

Steven D'Aprano

Ah, drat -- hit the wrong key and sent the last post before I had finished
writing it... the following is what I *intended* to send.

Maybe it was not too clear what I was trying to point out.

I have to calculate the time time.time() requires to return the next
tick of the clock.
Should be about 0.01ms but this may differ from os to os.

I suspect that Python isn't quite fast enough to give an accurate measure
for this, but I could be wrong.

You can try this:

def calc_time_res():
now = time.time
start = now()
x = start
while start == x:
x = now()
print x - start

Trying it, I get a fairly small number:
1.50203704834e-05

This is Python 2.3 running under Fedora Core 2 Linux.
 
R

Ron Adam

Steven said:
I suspect that Python isn't quite fast enough to give an accurate measure
for this, but I could be wrong.
2.40802764893e-05

Trying this on my win xp gives the following.


0.0150001049042 # time.time()

2.23492091872e-006 # time.clock()

2.7936511484e-006
1.95555580388e-006 #<- lowest value for time.clock()
1.95555580388e-006
1.95555580388e-006
3.35238137808e-006
1.95555580388e-006
1.95555580388e-006
1.95555580388e-006
2.23492091872e-006

But I think this is going to vary from system to system as well as what
os is used. And it may be effected by other tasks as well so checking
multiple times is probably needed.


def calc_time_res():
now = time.time
start = now()
x = start
while start == x:
x = now()
print x - start

def calc_time_res2():
now = time.clock
start = now()
x = start
while start == x:
x = now()
print x - start

def calc_time_res3():
now = time.clock
r = range(10)
times = [now() for x in r]
start = times[0]
for x in times[1:]:
print x-start
start = x

calc_time_res()
print
calc_time_res2()
print
calc_time_res3()
 
J

jUrner

def calc_time_res():
now = time.time
start = now()
x = start
while start == x:
x = now()
print x, start # <--
print x - start

print calc_time_res()
Something is going wrong here.
If you look at the function ,time.time() returns time in microseconds
(most oses and so
does mine).
So the calculation goes, lets say 1.23 - 1.24
How can the result be something like 1.50203704834e-05 ?
I would expect 0.01.

Next is, the first print statement prints out x and start equal up to
the fraction.

Is it Python giggeling?
Maybe it's python throwing the rounded float at us but internally
keeps calculating with the float returned by the os.
Maybe I'm wrong.
 
S

Steven D'Aprano

def calc_time_res():
now = time.time
start = now()
x = start
while start == x:
x = now()
print x, start # <--
print x - start

print calc_time_res()

Something is going wrong here.
If you look at the function ,time.time() returns time in microseconds
(most oses and so does mine).

From help(time.time):

time() -> floating point number
Return the current time in seconds since the Epoch.
Fractions of a second may be present if the system clock provides them.

Seconds, not microseconds.

So the calculation goes, lets say 1.23 - 1.24

How can the time *after* the while loop be less than the time *before* the
while loop?
How can the result be something like 1.50203704834e-05 ?

Have you looked at the output of time.time()?
1144496209.3221531

Of course, Python only prints a certain number of digits; to see the full
amount, use string formatting:
'1144496642.905987024307250976562500000000'


This brings me to an even simpler method of getting the resolution of
time.time(), without the overhead of a while loop:
1.0013580322265625e-05

which is approximately 0.01ms, just as you expected.
 
P

Peter Hansen

Steven said:
This brings me to an even simpler method of getting the resolution of
time.time(), without the overhead of a while loop:


1.0013580322265625e-05
which is approximately 0.01ms, just as you expected.

This doesn't necessarily work, at least on Windows, where the
time.time() resolution is much worse than the time it takes to execute a
couple of calls to time.time(). Most of the time the values returned by
two consecutive time.time() calls are identical, differing only if the
timer just happens to tick between the two. (On my machine a simple
while loop that performs the above calculation until it produces a
non-zero value has to run on average over 10000 times.)

-Peter
 
T

Tim Peters

[jUrner]
Don't confuse resolution with precision (or make up other words you
like better ;-)): just because some quantity is given with N bits
doesn't mean it's _accurate_ to N bits. See below for a more
extreme example.

[Steven D'Aprano]
...
This brings me to an even simpler method of getting the resolution of
time.time(), without the overhead of a while loop:

1.0013580322265625e-05

which is approximately 0.01ms, just as you expected.

Caution: the most likely outcome on Windows for that line is 0.0.
That's because the clock mechanism underlying time.time() on Windows
only updates at a frequency of 18.2 Hz (older systems) or 64 Hz (newer
systems). IOW, time.time() only "changes" 18.2 to 64 times per second
on Windows, and two consecutive calls are consequently likely to
return exactly the same result.

In contrast, time.clock() on Windows typically updates more than a
million times per second.
 
J

jUrner

Starts getting confusing...

on linux I get
print time.time()
Is it mentioned somewhere that print truncates floats ?
Thats new to me. Kinda surprising that is.

print '%.30' % time.time()I knew it must have been hiding somewhere

On windows I'd expect a resolution of round around 15ms. Thats why I
fell for the trap assuming linux is operating on about the same.
Anyway.
As far as I can see there is no nice way except for the brute force
loop
to calculate this resolution. This was giving me head sratches and
thats
why the loop in the initial post was so shamelessly empty. I was
thinking
about the poor dudes running an os with a resolution of about 1 second.
I was hoping for s.o. releasing an ace from his sleeve. Well, there
seems
to be no way to know except knowing.

Or like Sege Orlov put it
Crappy oses that is. Time for them to get standardized.
 
S

Sybren Stuvel

(e-mail address removed) enlightened us with:
Is it mentioned somewhere that print truncates floats ?

'print' prints str(time()). On the interactive prompt, you see
repr(time()). float.__str__ truncates. I don't know where it's
documented, but this is the reason why you see the truncation.

Sybren
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top