5
\$\begingroup\$
def stopWatchSeconds(secondCnt) :
    """ counts second for secondCnt seconds """

    # is there a better way to do this?
    startTime = time.clock()
    ellapsed = 0
    for x in range(0, secondCnt, 1) :
        print "loop cycle time: %f, seconds cnt: %02d" % (ellapsed , x)    
        ellapsed = 1 - (time.clock() - startTime)
        time.sleep(ellapsed)
        startTime = time.clock()

I'm reviewing some source code for a buddy of mine and came across this function. I am very new to Python so it is more of a learning experience for me. I see that he put in a comment about is there a better way to do this. I started thinking about it, and I know how I would do it in C#, but since python is so much more laxed it does seem like this function could be improved.

\$\endgroup\$
  • 1
    \$\begingroup\$ Could you give a little bit more info about the goal of this function? Is it for benchmarking, a timer, etc? Different goals might make different methods more appropriate. Also, time.clock() behaves differently on *nix systems vs Windows systems. What is the target platform? \$\endgroup\$ – Jacinda May 24 '13 at 6:54
  • \$\begingroup\$ Well the the program is to test a port by sending data for x amount of seconds on a Android device. \$\endgroup\$ – Robert Snyder May 24 '13 at 13:55
  • 1
    \$\begingroup\$ This seems like a reasonable approach to me (as a nitpick, elapsed should only have one 'l'). You might also be able to use the Python timeit module which has a default_timer that tracks wall clock time. \$\endgroup\$ – Jacinda May 26 '13 at 0:04
6
\$\begingroup\$

I'm not sure this code does what you think it does, at least on a *nix OS. According to the documentation, time.clock() returns processor time, which basically means that any time spent in time.sleep() is not counted. However, on Windows, time.clock() returns the actual time since it was first called.

A better way to determine the time since the function was first called is to use time.time(), which returns the number of seconds since the epoch. We can still use time.clock() to determine the process time if we are using a *nix OS. (If you are using Windows, you may want to upgrade to Python 3.3 which introduces the platform independent function time.process_time(). (There may be another way to do it if you are using 2.x, but I don't know what it is.)

#!/usr/bin/python
import time

def stopwatch(seconds):
    start = time.time()
    # time.time() returns the number of seconds since the unix epoch.
    # To find the time since the start of the function, we get the start
    # value, then subtract the start from all following values.
    time.clock()    
    # When you first call time.clock(), it just starts measuring
    # process time. There is no point assigning it to a variable, or
    # subtracting the first value of time.clock() from anything.
    # Read the documentation for more details.
    elapsed = 0
    while elapsed < seconds:
        elapsed = time.time() - start
        print "loop cycle time: %f, seconds count: %02d" % (time.clock() , elapsed) 
        time.sleep(1)  
        # You were sleeping in your original code, so I've stuck this in here...
        # You'll notice that the process time is almost nothing.
        # This is because we are spending most of the time sleeping,
        # which doesn't count as process time.
        # For funsies, try removing "time.sleep()", and see what happens.
        # It should still run for the correct number of seconds,
        # but it will run a lot more times, and the process time will
        # ultimately be a lot more. 
        # On my machine, it ran the loop 2605326 times in 20 seconds.
        # Obviously it won't run it more than 20 times if you use time.sleep(1)

stopwatch(20)

If you find the comments more confusing than helpful, here's a non-commented version...

#!/usr/bin/python
import time

def stopwatch(seconds):
    start = time.time()
    time.clock()    
    elapsed = 0
    while elapsed < seconds:
        elapsed = time.time() - start
        print "loop cycle time: %f, seconds count: %02d" % (time.clock() , elapsed) 
        time.sleep(1)  

stopwatch(20)
\$\endgroup\$
  • \$\begingroup\$ Thanks for pointing out the "processor time" distinction! I was wondering why time.clock() was reporting sub-second times around a 15-second HTTP request. \$\endgroup\$ – Ed Brannin Mar 14 '17 at 22:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.