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

Есть несколько способов сделать это. Наиболее эффективным способом было бы использовать URL.createObjectURL () в файле из вашего & lt; input & gt; . Передайте этот URL в img.src , чтобы сообщить браузеру загрузить предоставленное изображение.

Вот пример:



Вы также можете использовать FileReader.readAsDataURL () , чтобы проанализировать файл из вашего & lt; input & gt ;. Это создаст строку в памяти, содержащую представление base64 изображения.



1147
задан jww 10 December 2018 в 15:58
поделиться

5 ответов

Python включает профилировщика, вызванного cProfile. Это не только дает общему времени выполнения, но также и временам каждая функция отдельно, и говорит Вам, сколько раз каждая функция была вызвана, помогая определить, где необходимо сделать оптимизацию.

можно назвать его из кода, или от интерпретатора, как это:

import cProfile
cProfile.run('foo()')

Еще более полезно, можно вызвать cProfile при выполнении сценария:

python -m cProfile myscript.py

Для создания этого еще легче я сделал немного пакетного файла под названием 'profile.bat':

python -m cProfile %1

, Таким образом, все, что я должен сделать, выполняется:

profile 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}

РЕДАКТИРОВАНИЕ: Обновленная ссылка на хороший ресурс видео от PyCon 2013 назвала Python, Представляющий
Также через YouTube.

1256
ответ дан albert 11 December 2018 в 01:58
поделиться
  • 1
    @ccozad: Нет, массив не указатель на первый элемент. Массивы не являются указателями; указатели не являются массивами. Посмотрите кавычку из стандарта C99 в моем ответе. – Keith Thompson 16 August 2011 в 15:37

В Virtaal источник существует очень полезный класс и декоратор, который может сделать профилирование (даже для определенных методов/функций) очень легким. Вывод может тогда быть просмотрен очень удобно в KCacheGrind.

10
ответ дан Walter 11 December 2018 в 01:58
поделиться
  • 1
    @Dietrich: I' m знающий это it' s исторический; я имею в виду в том контексте. It' s интересный ответ, чтобы быть уверенным, но я don' t вполне видят ссылку между ним и почему это исторически не означало копирования массивов. Это могу просто быть я; можно ли помочь?:) – Lightness Races in Orbit 17 August 2011 в 23:22

Только для терминала (и самый простой) решение, если весь они представляют себе, что сбой UI устанавливает или работает:
игнорируют cProfile полностью и заменяют его pyinstrument, который соберет и отобразит дерево вызовов прямо после выполнения.

Установка:

$ pip install pyinstrument

Профиль и результат дисплея:

$ python -m pyinstrument ./prog.py

Работы с python2 и 3.

6
ответ дан 19 December 2019 в 20:15
поделиться

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

можно использовать этот cumulative_profiler декоратор:

это - Python> = 3,6 определенных, но можно удалить nonlocal для него, работают над более старыми версиями.

import cProfile, pstats

class _ProfileFunc:
    def __init__(self, func, sort_stats_by):
        self.func =  func
        self.profile_runs = []
        self.sort_stats_by = sort_stats_by

    def __call__(self, *args, **kwargs):
        pr = cProfile.Profile()
        pr.enable()  # this is the profiling section
        retval = self.func(*args, **kwargs)
        pr.disable()

        self.profile_runs.append(pr)
        ps = pstats.Stats(*self.profile_runs).sort_stats(self.sort_stats_by)
        return retval, ps

def cumulative_profiler(amount_of_times, sort_stats_by='time'):
    def real_decorator(function):
        def wrapper(*args, **kwargs):
            nonlocal function, amount_of_times, sort_stats_by  # for python 2.x remove this row

            profiled_func = _ProfileFunc(function, sort_stats_by)
            for i in range(amount_of_times):
                retval, ps = profiled_func(*args, **kwargs)
            ps.print_stats()
            return retval  # returns the results of the function
        return wrapper

    if callable(amount_of_times):  # incase you don't want to specify the amount of times
        func = amount_of_times  # amount_of_times is the function in here
        amount_of_times = 5  # the default amount
        return real_decorator(func)
    return real_decorator

Пример

профилирование функции baz

import time

@cumulative_profiler
def baz():
    time.sleep(1)
    time.sleep(2)
    return 1

baz()

baz работало 5 раз и распечатало это:

         20 function calls in 15.003 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10   15.003    1.500   15.003    1.500 {built-in method time.sleep}
        5    0.000    0.000   15.003    3.001 <ipython-input-9-c89afe010372>:3(baz)
        5    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

определение суммы времен

@cumulative_profiler(3)
def baz():
    ...
6
ответ дан 19 December 2019 в 20:15
поделиться

It's worth pointing out that using the profiler only works (by default) on the main thread, and you won't get any information from other threads if you use them. This can be a bit of a gotcha as it is completely unmentioned in the profiler documentation.

If you also want to profile threads, you'll want to look at the threading.setprofile() function in the docs.

You could also create your own threading.Thread subclass to do it:

class ProfiledThread(threading.Thread):
    # Overrides threading.Thread.run()
    def run(self):
        profiler = cProfile.Profile()
        try:
            return profiler.runcall(threading.Thread.run, self)
        finally:
            profiler.dump_stats('myprofile-%d.profile' % (self.ident,))

and use that ProfiledThread class instead of the standard one. It might give you more flexibility, but I'm not sure it's worth it, especially if you are using third-party code which wouldn't use your class.

191
ответ дан 19 December 2019 в 20:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: