Как получить время выполнения программы Python?

У меня есть программа командной строки в Python, который занимает некоторое время, чтобы закончить. Я хочу знать точное время, которое нужно, чтобы закончить бег.

и timeit module, но, похоже, это только для небольших фрагментов кода. Я хочу засечь время всей программы.

24 ответов


самый простой способ в Python:

import time
start_time = time.time()
main()
print("--- %s seconds ---" % (time.time() - start_time))

это предполагает, что ваша программа занимает по крайней мере десятую часть секунды для запуска.

принты:

--- 0.764891862869 seconds ---

Я положил это timing.py модуль в свои


в Linux или UNIX:

time python yourprogram.py

в Windows см. Это обсуждение Stackoverflow:как измерить время выполнения команды в командной строке windows?


import time

start_time = time.clock()
main()
print time.clock() - start_time, "seconds"

time.clock() возвращает процессорное время, что позволяет рассчитать только время, используемое этим процессом (в Unix в любом случае). В документации говорится:"в любом случае, это функция для использования для бенчмаркинга Python или алгоритмов синхронизации"


Мне очень нравится ответ пола Макгира, но я использую Python3. Итак, для тех, кому интересно: вот модификация его ответа, которая работает с Python 3 на *nix (я полагаю, под Windows, что часы () должны использоваться вместо time ()):

#python3
import atexit
from time import time, strftime, localtime
from datetime import timedelta

def secondsToStr(elapsed=None):
    if elapsed is None:
        return strftime("%Y-%m-%d %H:%M:%S", localtime())
    else:
        return str(timedelta(seconds=elapsed))

def log(s, elapsed=None):
    line = "="*40
    print(line)
    print(secondsToStr(), '-', s)
    if elapsed:
        print("Elapsed time:", elapsed)
    print(line)
    print()

def endlog():
    end = time()
    elapsed = end-start
    log("End Program", secondsToStr(elapsed))

start = time()
atexit.register(endlog)
log("Start Program")

Если вы считаете это полезным, вы все равно должны проголосовать за его ответ вместо этого, так как он сделал большую часть работы ;).


вы можете использовать профайл python profiler для измерения процессорного времени и дополнительно, сколько времени тратится внутри каждой функции и сколько раз вызывается каждая функция. Это очень полезно, если вы хотите улучшить производительность вашего скрипта, не зная, с чего начать. ответ к другому вопросу SO довольно хорошо. Всегда хорошо посмотреть в документы тоже.

вот пример того, как профилировать скрипт с помощью cProfile из командной строки:

$ python -m cProfile euler048.py

1007 function calls in 0.061 CPU seconds

Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.061    0.061 <string>:1(<module>)
 1000    0.051    0.000    0.051    0.000 euler048.py:2(<lambda>)
    1    0.005    0.005    0.061    0.061 euler048.py:2(<module>)
    1    0.000    0.000    0.061    0.061 {execfile}
    1    0.002    0.002    0.053    0.053 {map}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler objects}
    1    0.000    0.000    0.000    0.000 {range}
    1    0.003    0.003    0.003    0.003 {sum}

мне нравится вывод datetime модуль обеспечивает, где объекты перепада времени показывают дни, часы, минуты etc. по мере необходимости в удобочитаемом виде.

например:

from datetime import datetime
start_time = datetime.now()
# do your work here
end_time = datetime.now()
print('Duration: {}'.format(end_time - start_time))

пример вывода, например

Duration: 0:00:08.309267

или

Duration: 1 day, 1:51:24.269711

обновление:

import time
from datetime import timedelta
start_time = time.monotonic()
end_time = time.monotonic()
print(timedelta(seconds=end_time - start_time))


еще лучше для Linux: /usr/bin/time

$ /usr/bin/time -v python rhtest2.py

    Command being timed: "python rhtest2.py"
    User time (seconds): 4.13
    System time (seconds): 0.07
    Percent of CPU this job got: 91%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:04.58
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 0
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 15
    Minor (reclaiming a frame) page faults: 5095
    Voluntary context switches: 27
    Involuntary context switches: 279
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

нормально, просто time является более простой оболочкой, построенной, что тени более способны /usr/bin/time.


решение rogeriopvl отлично работает, но если вам нужна более конкретная информация, вы можете использовать встроенный профилировщик python. Проверьте эту страницу:

http://docs.python.org/library/profile.html

профилировщик говорит вам много полезной информации, такой как время, проведенное в каждой функции


следующий фрагмент печатает истекшее время в хорошем читаемом человеком .

import time
from datetime import timedelta

start_time = time.time()

#
# Perform lots of computations.
#

elapsed_time_secs = time.time() - start_time

msg = "Execution took: %s secs (Wall clock time)" % timedelta(seconds=round(elapsed_time_secs))

print(msg)    

from time import time
start_time = time()
...
end_time = time()
time_taken = end_time - start_time # time_taken is in seconds
hours, rest = divmod(time_taken,3600)
minutes, seconds = divmod(rest, 60)

я посмотрел на модуль timeit, но, похоже, это только для небольших фрагментов кода. Я хочу засечь время всей программы.

$ python -mtimeit -n1 -r1 -t -s "from your_module import main" "main()"

он работает your_module.main() функция один раз и печать прошедшего времени с помощью в качестве таймера.

эмуляция /usr/bin/time в Python вижу подпроцесс Python с /usr/bin / time: как захватить информацию о времени, но игнорировать все остальные выходные данные?.

для измерения времени процессора (например, не включают время time.sleep()) для каждой функции вы можете использовать profile модуль (cProfile на Python 2):

$ python3 -mprofile your_module.py

вы могли бы пройти -p to timeit команда выше, если вы хотите использовать тот же таймер, как profile модуль использует.

посмотреть как вы можете профилировать скрипт Python?


Ipython "timeit" любой скрипт:

def foo():
    %run bar.py
timeit foo()

времени.clock()

устарел с версии 3.3: поведение этой функции зависит на платформе: используйте perf_counter () или process_time() , в зависимости от ваших требований, иметь четко определенное поведение.

времени.perf_counter()

возвращает значение (в дробных секундах) счетчика производительности, т. е. часы с самым высоким доступным разрешением для измерения короткого продолжительность. Это тут включить время, прошедшее во время сна и общесистемный.

времени.process_time()

возвращает значение (в дробных секундах) суммы системы и время использования процессора для текущего процесса. Это не включить времени во время сна.

start = time.process_time()
... do something
elapsed = (time.process_time() - start)

Просто Использовать timeit модуль. Он работает как с Python 2, так и с Python 3

import timeit

start = timeit.default_timer()
#ALL THE PROGRAM STATEMETNS
stop = timeit.default_timer()
execution_time = stop - start

print("Program Executed in "+execution_time) #It returns time in sec

он возвращается через несколько секунд, и Вы можете иметь время выполнения. Просто, но вы должны написать их в основной функции, которая запускает выполнение программы. Если вы хотите получить время выполнения, даже если вы получаете ошибку, то возьмите свой параметр "Start" и вычислите его как

def sample_function(start,**kwargs):
     try:
         #your statements
     Except:
         #Except Statements
         stop = timeit.default_timer()
         execution_time = stop - start
         print("Program Executed in "+execution_time)

есть timeit модуль, который может использоваться для времени выполнения кодов python. Он имеет подробную документацию и примеры в документах python (https://docs.python.org/2/library/timeit.html)


Мне тоже нравится ответ пола Макгира и придумал форму контекстного менеджера, которая больше соответствовала моим потребностям.

import datetime as dt
import timeit

class TimingManager(object):
    """Context Manager used with the statement 'with' to time some execution.

    Example:

    with TimingManager() as t:
       # Code to time
    """

    clock = timeit.default_timer

    def __enter__(self):
        """
        """
        self.start = self.clock()
        self.log('\n=> Start Timing: {}')

        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        """
        self.endlog()

        return False

    def log(self, s, elapsed=None):
        """Log current time and elapsed time if present.
        :param s: Text to display, use '{}' to format the text with
            the current time.
        :param elapsed: Elapsed time to display. Dafault: None, no display.
        """
        print s.format(self._secondsToStr(self.clock()))

        if(elapsed is not None):
            print 'Elapsed time: {}\n'.format(elapsed)

    def endlog(self):
        """Log time for the end of execution with elapsed time.
        """
        self.log('=> End Timing: {}', self.now())

    def now(self):
        """Return current elapsed time as hh:mm:ss string.
        :return: String.
        """
        return str(dt.timedelta(seconds = self.clock() - self.start))

    def _secondsToStr(self, sec):
        """Convert timestamp to h:mm:ss string.
        :param sec: Timestamp.
        """
        return str(dt.datetime.fromtimestamp(sec))

это ответ пола Макгира, который работает для меня. На случай, если у кого-то возникнут проблемы с управлением.

import atexit
from time import clock

def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value

def secondsToStr(t):
    return "%d:%02d:%02d.%03d" % \
        reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
            [(t*1000,),1000,60,60])

line = "="*40
def log(s, elapsed=None):
    print (line)
    print (secondsToStr(clock()), '-', s)
    if elapsed:
        print ("Elapsed time:", elapsed)
    print (line)

def endlog():
    end = clock()
    elapsed = end-start
    log("End Program", secondsToStr(elapsed))

def now():
    return secondsToStr(clock())

def main():
    start = clock()
    atexit.register(endlog)
    log("Start Program")

вызов timing.main() из вашей программы после импорта файла.


Timeit-класс в python, используемый для вычисления времени выполнения небольших блоков кода.

Default_timer-это метод в этом классе, который используется для измерения времени настенных часов, а не времени выполнения процессора. Таким образом, этому может помешать другое выполнение процесса. Таким образом, он полезен для небольших блоков кода.

пример кода выглядит следующим образом:

from timeit import default_timer as timer

start= timer()

#some logic 

end = timer() 

print("Time taken:", end-start) 

использовать line_profiler.

line_profiler будет профилировать время выполнения отдельных строк кода. Профилировщик реализован в C через Cython, чтобы уменьшить накладные расходы на профилирование.

from line_profiler import LineProfiler
import random

def do_stuff(numbers):
    s = sum(numbers)
    l = [numbers[i]/43 for i in range(len(numbers))]
    m = ['hello'+str(numbers[i]) for i in range(len(numbers))]

numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()

результаты будут:

Timer unit: 1e-06 s

Total time: 0.000649 s
File: <ipython-input-2-2e060b054fea>
Function: do_stuff at line 4

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     4                                           def do_stuff(numbers):
     5         1           10     10.0      1.5      s = sum(numbers)
     6         1          186    186.0     28.7      l = [numbers[i]/43 for i in range(len(numbers))]
     7         1          453    453.0     69.8      m = ['hello'+str(numbers[i]) for i in range(len(numbers))]

для людей данных, использующих Jupyter Notebooks

в ячейку, вы можете использовать Jupyter это %%time волшебная команда для измерения времени выполнения:

%%time 
[ x**2 for x in range(10000)] 

выход
Время процессора: пользователь 4.54 ms, sys: 0 ns, всего: 4.54 ms
Время стены: 4,12 МС

это будет захватывать только время выполнения конкретной ячейки. Если вы хотите записать время выполнения всего ноутбука (т. е. программы), вы можете создать новый ноутбук в тот же каталог и в новом ноутбуке выполните все ячейки:

предположим, что записная книжка выше называется example_notebook.ipynb. В новом блокноте в том же каталоге:

# Convert your notebook to a .py script:
!jupyter nbconvert --to script example_notebook.ipynb

# Run the example_notebook with -t flag for time
%run -t example_notebook

выход
IPython тайминги процессора (оценочные): Пользователь: 0.00 s.
Система: 0.00 s.
Время стены: 0.00 s.


использовать обновленный ответ metakermit для python 2.7 вам потребуется монотонная.

код будет выглядеть следующим образом:
from datetime import timedelta
from monotonic import monotonic

start_time = monotonic()
end_time = monotonic()
print(timedelta(seconds=end_time - start_time))

время выполнения программы Python может быть несовместимым в зависимости от:

  • та же программа может быть оценена с использованием различных алгоритмов
  • время работы зависит от алгоритмов
  • время выполнения варьируется между реализациями
  • время работы варьируется между компьютерами
  • время работы не предсказуемо на основе небольших входов

Это потому, что наиболее эффективным способом является использование "Порядок роста" и выучите большую нотацию "о", Чтобы сделать это правильно,https://en.wikipedia.org/wiki/Big_O_notation

в любом случае вы можете попытаться оценить производительность любой программы Python в конкретных шагах подсчета машин в секунду, используя этот простой алгоритм: адаптируйте это к программе, которую вы хотите оценить

import time

now = time.time()
future = now + 10
step = 4 # why 4 steps? because until here already 4 operations executed
while time.time() < future:
    step += 3 # why 3 again? because while loop execute 1 comparison and 1 plus equal statement
step += 4 # why 3 more? because 1 comparison starting while when time is over plus final assignment of step + 1 and print statement
print(str(int(step / 10)) + " steps per second")

надеюсь, это поможет вам.


я использовал очень простую функцию для синхронизации части выполнения кода:

import time
def timing():
    start_time = time.time()
    return lambda x: print("[{:.2f}s] {}".format(time.time() - start_time, x))

и использовать его, просто вызовите его перед кодом для измерения, чтобы получить функцию синхронизации, затем вызовите функцию после кода с комментариями, и время появится перед комментариями, например:

t = timing()
train = pd.read_csv('train.csv',
                        dtype={
                            'id': str,
                            'vendor_id': str,
                            'pickup_datetime': str,
                            'dropoff_datetime': str,
                            'passenger_count': int,
                            'pickup_longitude': np.float64,
                            'pickup_latitude': np.float64,
                            'dropoff_longitude': np.float64,
                            'dropoff_latitude': np.float64,
                            'store_and_fwd_flag': str,
                            'trip_duration': int,
                        },
                        parse_dates = ['pickup_datetime', 'dropoff_datetime'],
                   )
t("Loaded {} rows data from 'train'".format(len(train)))

тогда выход будет выглядеть так:

[9.35s] Loaded 1458644 rows data from 'train'

Я чувствую себя немного элегантной таким образом.