Python speed testing - Time Difference - milliseconds
Asked Answered
E

16

193

What is the proper way to compare 2 times in Python in order to speed test a section of code? I tried reading the API docs. I'm not sure I understand the timedelta thing.

So far I have this code:

from datetime import datetime

tstart = datetime.now()
print t1

# code to speed test

tend = datetime.now()
print t2
# what am I missing?
# I'd like to print the time diff here
Extractor answered 19/4, 2009 at 23:8 Comment(2)
Why didn't you print t2-t1? What stopped you from subtracting?Protium
Guess, I had the "it couldn't be that easy" moment.Extractor
A
258

datetime.timedelta is just the difference between two datetimes ... so it's like a period of time, in days / seconds / microseconds

>>> import datetime
>>> a = datetime.datetime.now()
>>> b = datetime.datetime.now()
>>> c = b - a

>>> c
datetime.timedelta(0, 4, 316543)
>>> c.days
0
>>> c.seconds
4
>>> c.microseconds
316543

Be aware that c.microseconds only returns the microseconds portion of the timedelta! For timing purposes always use c.total_seconds().

You can do all sorts of maths with datetime.timedelta, eg:

>>> c / 10
datetime.timedelta(0, 0, 431654)

It might be more useful to look at CPU time instead of wallclock time though ... that's operating system dependant though ... under Unix-like systems, check out the 'time' command.

Amharic answered 19/4, 2009 at 23:31 Comment(5)
Anyone interested in getting total minutes can use int(c.total_seconds() / 60) in this caseEllora
The page for the timeit module says that the module "avoids a number of common traps for measuring execution times." Is this approach (using datetime.now) subject to any of those pitfalls?Coronet
@Coronet yes, it is! It is would be better to use timeit instead of this method! For example, I have a test in a large python project that, when measured using this method results in a supposed 0.25s runtime. In reality, and according to timeit, the runtime of said function is actually 30 seconds!Appalling
this is not usable for accurate timing since datetime is not a monotonic clockAccelerando
This appears to measure the wrong time if your Python program calls C++ code via CPython.Preponderate
E
88

Since Python 2.7 there's the timedelta.total_seconds() method. So, to get the elapsed milliseconds:

>>> import datetime
>>> a = datetime.datetime.now()
>>> b = datetime.datetime.now()
>>> delta = b - a
>>> print delta
0:00:05.077263
>>> int(delta.total_seconds() * 1000) # milliseconds
5077
Earthward answered 17/6, 2014 at 22:38 Comment(4)
How to accurately show this in milliseconds?Ocd
@Ocd - It is accurateCanoe
Actually, this doesn't work if execution time is under 1 sec. delta.total_seconds() returns 0, and thus, you cannot measure the millisecondsFilet
Yeah, this didn't work for me, show 0sec for a bdd queryLabyrinthodont
S
38

You might want to use the timeit module instead.

Schnapp answered 20/4, 2009 at 0:18 Comment(0)
H
33

I know this is late, but I actually really like using:

import time
start = time.time()

##### your timed code here ... #####

print "Process time: " + (time.time() - start)

time.time() gives you seconds since the epoch. Because this is a standardized time in seconds, you can simply subtract the start time from the end time to get the process time (in seconds). time.clock() is good for benchmarking, but I have found it kind of useless if you want to know how long your process took. For example, it's much more intuitive to say "my process takes 10 seconds" than it is to say "my process takes 10 processor clock units"

>>> start = time.time(); sum([each**8.3 for each in range(1,100000)]) ; print (time.time() - start)
3.4001404476250935e+45
0.0637760162354
>>> start = time.clock(); sum([each**8.3 for each in range(1,100000)]) ; print (time.clock() - start)
3.4001404476250935e+45
0.05

In the first example above, you are shown a time of 0.05 for time.clock() vs 0.06377 for time.time()

>>> start = time.clock(); time.sleep(1) ; print "process time: " + (time.clock() - start)
process time: 0.0
>>> start = time.time(); time.sleep(1) ; print "process time: " + (time.time() - start)
process time: 1.00111794472

In the second example, somehow the processor time shows "0" even though the process slept for a second. time.time() correctly shows a little more than 1 second.

Hierarchy answered 16/5, 2014 at 16:32 Comment(0)
I
24

You could also use:

import time

start = time.clock()
do_something()
end = time.clock()
print "%.2gs" % (end-start)

Or you could use the python profilers.

Impair answered 19/4, 2009 at 23:38 Comment(1)
When using start = time.clock() it prints DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead.Disc
H
6

The following code should display the time detla...

from datetime import datetime

tstart = datetime.now()

# code to speed test

tend = datetime.now()
print tend - tstart
Hurt answered 19/4, 2009 at 23:17 Comment(0)
T
4

You could simply print the difference:

print tend - tstart
Trinatte answered 19/4, 2009 at 23:16 Comment(0)
I
4

You may want to look into the profile modules. You'll get a better read out of where your slowdowns are, and much of your work will be full-on automated.

Iaea answered 19/4, 2009 at 23:41 Comment(1)
Nice idea! Thanks.Extractor
F
3

I am not a Python programmer, but I do know how to use Google and here's what I found: you use the "-" operator. To complete your code:

from datetime import datetime

tstart = datetime.now()

# code to speed test

tend = datetime.now()
print tend - tstart

Additionally, it looks like you can use the strftime() function to format the timespan calculation in order to render the time however makes you happy.

Fibrinolysin answered 19/4, 2009 at 23:17 Comment(0)
F
3

Arrow: Better dates & times for Python

import arrow
start_time = arrow.utcnow()
end_time = arrow.utcnow()
(end_time - start_time).total_seconds()  # senconds
(end_time - start_time).total_seconds() * 1000  # milliseconds
Fogbow answered 12/2, 2020 at 14:35 Comment(0)
I
3

You need to use time.time() instead, which outputs unix time with high precision.

Use this code:

from time import time

tstart = time()
doSomething()
tend = time()
difference = tend - tstart
print("The doSomething function took {} seconds to execute".format(difference))
Ides answered 4/11, 2021 at 12:41 Comment(0)
K
2

time.time() / datetime is good for quick use, but is not always 100% precise. For that reason, I like to use one of the std lib profilers (especially hotshot) to find out what's what.

Knotgrass answered 19/4, 2009 at 23:19 Comment(0)
T
2

Here is a custom function that mimic's Matlab's/Octave's tic toc functions.

Example of use:

time_var = time_me(); # get a variable with the current timestamp

... run operation ...

time_me(time_var); # print the time difference (e.g. '5 seconds 821.12314 ms')

Function :

def time_me(*arg):
    if len(arg) != 0: 
        elapsedTime = time.time() - arg[0];
        #print(elapsedTime);
        hours = math.floor(elapsedTime / (60*60))
        elapsedTime = elapsedTime - hours * (60*60);
        minutes = math.floor(elapsedTime / 60)
        elapsedTime = elapsedTime - minutes * (60);
        seconds = math.floor(elapsedTime);
        elapsedTime = elapsedTime - seconds;
        ms = elapsedTime * 1000;
        if(hours != 0):
            print ("%d hours %d minutes %d seconds" % (hours, minutes, seconds)) 
        elif(minutes != 0):
            print ("%d minutes %d seconds" % (minutes, seconds))
        else :
            print ("%d seconds %f ms" % (seconds, ms))
    else:
        #print ('does not exist. here you go.');
        return time.time()
Tarah answered 20/10, 2016 at 17:54 Comment(1)
Traceback (most recent call last): File "redis-get-response.py", line 22, in <module> time_var = time_me(); # get a variable with the current timestamp File "redis-get-response.py", line 20, in time_me return time.time() NameError: name 'time' is not definedThema
D
0

You could use timeit like this to test a script named module.py

$ python -mtimeit -s 'import module'
Dunseath answered 27/9, 2012 at 8:41 Comment(0)
H
0
start = datetime.now() 

#code for which response time need to be measured.

end = datetime.now()
dif = end - start
dif_micro = dif.microseconds # time in microseconds
dif_millis = dif.microseconds / 1000 # time in millisseconds
Harbin answered 24/2, 2021 at 4:18 Comment(1)
While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn and eventually apply that knowledge to their own code. You are also likely to have positive feedback/upvotes from users, when the code is explained.Selfseeker
D
0

In case anyone needs something like this to analyze delays between log entries for example ... etc.

def get_time_diff_between_timestruct_tuples(timestruct_tuples):
    """
    expecting input like:
    [(0, datetime.datetime(2021, 10, 27, 16, 6, 8, 590892)),
    (1, datetime.datetime(2021, 10, 27, 16, 6, 8, 591833)),
    (2, datetime.datetime(2021, 10, 27, 16, 6, 9, 434053)),
    (3, datetime.datetime(2021, 10, 27, 16, 6, 9, 878021)), ...]
    
    output like:
    [0.941, 0.84222, 0.443968, ...]
    """
    
    def seconds_mms_diff(t0, t1):
        diff = t1 - t0
        s = diff.seconds
        mms = diff.microseconds
        return float(f"{s}.{mms}")
    
    timediffs = []
    init = timestruct_tuples[0][1]
    idx = 0
    while idx < (len(timestruct_tuples)-1):
        timediffs.append(seconds_mms_diff(init, timestruct_tuples[idx+1][1]))
        idx += 1
        init = timestruct_tuples[idx][1]
    return timediffs
Dinghy answered 29/10, 2021 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.