views:

146

answers:

3

I'm posing this question mostly out of curiosity. I've written some code that is doing some very time intensive work. So, before executing my workhorse function, I wrapped it up in a couple of calls to time.clock(). It looks something like this:

t1 = time.clock()
print this_function_takes_forever(how_long_parameter = 20)
t2 = time.clock()
print t2 - t1

This worked fine. My function returned correctly and t2 - t1 gave me a result of 972.29, or about 16 minutes.

However, when I changed my code to this

t1 = time.clock()
print this_function_takes_forever(how_long_parameter = 80)
t2 = time.clock()
print t2 - t1

My function still returned fine, but the result of t2 - t1 was:

None
-1741

I'm curious as to what implementation detail causes this. Both the None, and the negative number are perplexing to me. Does it have something to do with a signed type? How does this explain the None?

+2  A: 

A quick guess... Looks like an overflow. The default data type is probably a signed data type (putting the first bit to 1 on a signed integer gives a negative number).

Try putting the result of the substraction in a variable (double), and then printing that.

If it still prints like that, you can try converting it from double to string, and then using 'print' function on the string.

Wadih M.
There's no signed shorts in python...
Eloff
Ok, I've generalized the description. The concept would be the same.
Wadih M.
@Eloff: But `time.clock()` takes result from the system...
KennyTM
If the code snippet is running on the same system, i wouldn't see a scenario where t2 is smaller than t1. Unless python behaves completely differently.
Wadih M.
@Wadih, no the result wont be the same, because time.clock() returns a double, unless your theory is that the underlying python or platform implementation has an overflow bug, which may well be possible, but I find it highly dubious.
Eloff
it seems sth's answer is the right one. Clock() doesn't give the amount of seconds since like 1st jan 1970, it's range is limited and has a modulo of 72 minutes. voting him up
Wadih M.
numeric types will (almost) never overflow in python. They just go Long. Try `2**10000000` and see http://docs.python.org/library/exceptions.html#exceptions.OverflowError
Wayne Werner
@Wayne: `2.0**10000000`. Note that `time.clock()` returns a float.
KennyTM
Thanks for info!
Wadih M.
"Because of the lack of standardization of floating point exception handling in C, most floating point operations also aren’t checked." - I suppose I was a technically incorrect combining `numeric` and `almost`. Floating points *can* overflow, but it's quite large, past `100000.0*24*60*60.0`.
Wayne Werner
+1  A: 

The None has a very simple answer, your function does not return a value. Actually I gather that is does under normal circumstances, but not when how_long_parameter = 80. Because your function seems to be returning early (probably because execution reaches the end of the function where there is an implicit return None in Python) the negative time might be because your function takes almost no time to complete in this case? So look for the bug in your function and correct it.

The actual answer as to why you get a negative time depends on the operating system you are using, because clock() is implemented differently on different platforms. On Windows it uses QueryPerformanceCounter(), on *nix it uses the C function clock().

Eloff
You're right. On both the fact that my function doesn't return anything for that parameter, and that that was a very simple answer. Thanks.
Wilduck
+14  A: 

The Python docs say:

On Unix, return the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning of “processor time”, depends on that of the C function of the same name

The manpage of the referenced C function then explains the issue:

Note that the time can wrap around. On a 32-bit system where CLOCKS_PER_SEC equals 1000000 this function will return the same value approximately every 72 minutes.

sth