파이썬 스크립트를 어떻게 프로파일 링 할 수 있습니까?


1283

프로젝트 오일러 및 기타 코딩 공모전은 종종 최대 실행 시간을 갖거나 사람들이 특정 솔루션의 실행 속도를 자랑합니다. 파이썬의 경우 때때로 접근 방식이 다소 복잡합니다 __main__. 즉 타이밍 코드를 추가하는 것 입니다.

파이썬 프로그램 실행 시간을 프로파일 링하는 좋은 방법은 무엇입니까?


113
프로젝트 오일러 프로그램은 프로파일 링이 필요하지 않습니다. 1 분 안에 작동하는 알고리즘이 있거나 완전히 잘못된 알고리즘이 있습니다. "튜닝"은 거의 적합하지 않습니다. 일반적으로 새로운 접근 방식을 취해야합니다.
S.Lott

105
S. 로트 : 프로파일 링은 종종 어떤 서브 루틴이 느린 지 결정하는 데 유용한 방법입니다. 시간이 오래 걸리는 서브 루틴은 알고리즘 개선의 훌륭한 후보입니다.
stalepretzel

답변:


1369

파이썬에는 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 Profiling
Also YouTube를 통해 좋은 비디오 리소스에 대한 링크가 업데이트 되었습니다 .


251
또한 -s 스위치로 수행 할 수있는 결과를 정렬하는 것이 유용합니다 (예 : '-s time'). 누적 / 이름 / 시간 / 파일 정렬 옵션을 사용할 수 있습니다.
Jiri

19
또한 매직 함수 % prun (프로파일 실행)을 사용하여 ipython에서 cProfile 모듈을 사용할 수 있습니다. 먼저 모듈을 가져온 다음 % prun을 사용하여 기본 함수를 호출하십시오. import euler048; % prun euler048.main ()
RussellStewart 2014 년

53
cProfile 덤프 (에서 만든 python -m cProfile -o <out.profile> <script>) 를 시각화하기 위해 RunSnakeRunrunsnake <out.profile> 이 매우 중요하게 호출 되었습니다.
Lily Chung

13
python 3에서도 @NeilG cprofile가 권장 됩니다 profile.
trichoplax

17
cProfile 덤프를 시각화하기 위해 RunSnakeRun은 2011 년 이후로 업데이트되지 않았으며 python3을 지원하지 않습니다. 대신 snakeviz 를 사용해야 합니다
Giacomo Tecya Pigani

423

얼마 전에 pycallgraph파이썬 코드에서 시각화를 생성했습니다. 편집 : 이 글을 쓰는 시점에서 최신 릴리스 3.3으로 작동하도록 예제를 업데이트했습니다.

GraphVizpip install pycallgraph설치 한 후 명령 행에서 실행할 수 있습니다.

pycallgraph graphviz -- ./mypythonscript.py

또는 코드의 특정 부분을 프로파일 링 할 수 있습니다.

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

with PyCallGraph(output=GraphvizOutput()):
    code_to_profile()

이들 중 하나가 pycallgraph.png아래 이미지와 유사한 파일 을 생성 합니다.

여기에 이미지 설명을 입력하십시오


43
통화량을 기준으로 채색하고 있습니까? 그렇다면 가장 많은 통화를하는 함수가 항상 가장 많은 시간을 소비하는 함수는 아니기 때문에 시간에 따라 색상을 지정해야합니다.
빨간

21
@red 원하는대로 색상을 사용자 정의 할 수 있으며 각 측정에 대해 독립적으로도 가능합니다. 예를 들어 통화의 경우 빨간색, 시간의 경우 파란색, 메모리 사용의 경우 녹색입니다.
gak

2
이 오류가Traceback (most recent call last): /pycallgraph.py", line 90, in generate output.done() File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 94, in done source = self.generate() File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 143, in generate indent_join.join(self.generate_attributes()), File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 169, in generate_attributes section, self.attrs_from_dict(attrs), ValueError: zero length field name in format
Ciasto을 piekarz

3
설명에 따라 작동하려면 GraphViz를 설치해야한다고 언급하기 위해 이것을 업데이트했습니다. 우분투에서 이것은 단지 sudo apt-get install graphviz입니다.
mlissner

2
여기에 설치하려면 약간의 작업이 필요합니다. 도움이되는 3 단계입니다. 1. pip를 통해 설치합니다. 2. exe를 통해 GraphViz를 설치합니다. 3. GraphViz 디렉토리에 경로 변수를 설정합니다. 4. 다른 모든 오류를 수정하는 방법을 알아 봅니다. 5. png 파일을 저장할 위치를 찾으십니까?
습지

199

프로파일 러를 사용하면 기본 스레드에서만 작동하며 기본 스레드를 사용하는 경우 다른 스레드에서 정보를 얻지 못합니다. 이것은 프로파일 러 문서 에서 완전히 언급되지 않았기 때문에 약간의 문제가 될 수 있습니다 .

스레드를 프로파일 링하려면 함수 를 살펴보고 싶을 것입니다threading.setprofile() 하려면 문서 입니다.

자신 만의 threading.Thread서브 클래스를 만들어서 수행 할 수도 있습니다 .

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,))

ProfiledThread표준 클래스 대신 해당 클래스를 사용하십시오. 그것은 당신에게 더 많은 유연성을 줄 수 있지만, 특히 클래스를 사용하지 않는 타사 코드를 사용하는 경우 가치가 있는지 확실하지 않습니다.


1
설명서에 runcall에 대한 참조가 없습니다. cProfile.py를 살펴보면 왜 threading.Thread.run 함수 또는 self를 인수로 사용하는지 잘 모르겠습니다. 여기 에서 다른 스레드의 실행 방법에 대한 참조가 필요 합니다.
PypeBros

설명서에는 없지만 모듈에 있습니다. hg.python.org/cpython/file/6bf07db23445/Lib/cProfile.py#l140을 참조하십시오 . 이를 통해 특정 함수 호출을 프로파일 링 할 수 있으며 target,이 경우 threading.Thread.run()호출이 실행 하는 스레드의 함수 를 프로파일 링하려고합니다 . 그러나 대답에서 말했듯이 타사 코드는 사용하지 않고 대신을 사용하기 때문에 Thread를 서브 클래스 화하는 것은 가치가 없습니다 threading.setprofile().
Joe Shaw

9
profiler.enable () 및 profiler.disable ()으로 코드를 래핑하면 꽤 잘 작동하는 것 같습니다. 그것은 기본적으로 runcall 이하는 일이며 많은 논쟁이나 유사한 것들을 강요하지 않습니다.
PypeBros

1
나는 내 자신의 stackoverflow.com/questions/10748118/…ddaa.net/blog/python/lsprof-calltree 와 결합 했고 그것은 일종의 작동;!-)
Dima Tisnek

1
Joe, Python 3.4에서 프로파일 러가 asyncio와 어떻게 작동하는지 알고 있습니까?
Nick Chammas 2016 년

148

Python Wiki는 리소스 프로파일 링을위한 훌륭한 페이지입니다. http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code

파이썬 문서와 마찬가지로 : http://docs.python.org/library/profile.html

Chris Lawlor가 보여주는 것처럼 cProfile은 훌륭한 도구이며 화면에 쉽게 인쇄 할 수 있습니다.

python -m cProfile -s time mine.py <args>

또는 파일 :

python -m cProfile -o output.file mine.py <args>

PS> Ubuntu를 사용하는 경우 python-profile을 설치하십시오

apt-get install python-profiler 

파일로 출력하면 다음 도구를 사용하여 멋진 시각화를 얻을 수 있습니다

PyCallGraph : 콜 그래프 이미지를 생성하는 도구
설치 :

 pip install pycallgraph

운영:

 pycallgraph mine.py args

전망:

 gimp pycallgraph.png

당신은 당신이 PNG 파일을보고 싶은대로 사용할 수 있습니다, 나는 김프를 사용
불행하게도 나는 종종 얻는다.

점 : Cairo- 렌더러 비트 맵에 그래프가 너무 큽니다. 적합하도록 0.257079 확장

내 이미지를 사용할 수 없을 정도로 작게 만듭니다. 따라서 일반적으로 svg 파일을 만듭니다.

pycallgraph -f svg -o pycallgraph.svg mine.py <args>

PS>는 graphviz를 설치해야합니다 (도트 프로그램을 제공합니다).

pip install graphviz

@maxy / @quodlibetor를 통해 gprof2dot를 사용한 대체 그래프 :

pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg

12
gprof2dot 도 이러한 그래프를 수행 할 수 있습니다. 나는 출력이 조금 더 좋다고 생각한다 ( ).
maxy

2
OSX를 사용하는 경우 graphviz도 필요합니다
Vaibhav Mishra

134

이 답변에 대한 @Maxy의 의견 은 자체 답변이 필요하다고 생각할 정도로 충분히 도움 되었습니다. 나는 이미 cProfile 생성 .pstats 파일을 가지고 있었고 pycallgraph로 물건을 다시 실행하고 싶지 않기 때문에 gprof2dot을 사용 하여 꽤 예뻤습니다. svgs :

$ sudo apt-get install graphviz
$ git clone https://github.com/jrfonseca/gprof2dot
$ ln -s "$PWD"/gprof2dot/gprof2dot.py ~/bin
$ cd $PROJECT_DIR
$ gprof2dot.py -f pstats profile.pstats | dot -Tsvg -o callgraph.svg

그리고 BLAM!

도트 (pycallgraph와 동일한 것)를 사용하므로 출력이 비슷해 보입니다. gprof2dot가 정보를 덜 잃는다는 인상을 얻습니다.

gprof2dot 예제 출력


1
좋은 접근 방식, Chrome 등에서 SVG를보고 확대 / 축소 할 수 있으므로 실제로 효과적입니다. 세 번째 줄에는 오타가 있어야합니다. ln -s pwd/gprof2dot/gprof2dot.py $ HOME / bin 버전).
RichVel

2
아, 좋은 지적입니다. 나는 수 ln의 인수 차 잘못된 거의 모든 시간을.
quodlibetor

7
트릭은 ln과 cp의 인수 순서가 동일하다는 것을 기억하는 것입니다. 'file1을 file2 또는 dir2에 복사하지만 링크를 만드는 것'으로 생각하십시오.
RichVel

맨 페이지에서 "TARGET"을 사용하면 문제가 발생한다고 생각합니다.
quodlibetor

어떻게 모서리를 둥글게 했습니까? 가독성이 향상되었다고 생각합니다. 상자 주위에 많은 모서리가있는 경우 시원하지 않은 못생긴 날카로운 모서리가 나타납니다.
Hibou57

77

이 주제를 연구 할 때 SnakeViz 라는 편리한 도구를 사용했습니다 . SnakeViz는 웹 기반 프로파일 링 시각화 도구입니다. 설치 및 사용이 매우 쉽습니다. 내가 사용하는 일반적인 방법은 stat 파일을 생성하는 것입니다.%prun 은 SnakeViz에서 다음 분석하는 것입니다.

사용되는 주요 viz 기술은 햇살 차트입니다. 아래와 같이 로, 함수 호출의 계층 구조는 각도 폭으로 인코딩 된 호 및 시간 정보 레이어로 배열됩니다.

가장 좋은 것은 차트와 상호 작용할 수 있다는 것입니다. 예를 들어, 확대하려면 호를 클릭하면 호와 그 자손이 새로운 햇살로 확대되어 더 자세한 정보를 표시합니다.

여기에 이미지 설명을 입력하십시오


1
CodeCabbie의 답변 에는 (짧은) 설치 지침이 포함되어 있으며 SnakeViz 를 (쉽게) 사용하는 방법이 나와 있습니다.
오렌 Milman

여기에 내가 읽은 이럴 좋은 가이드는 어떻게 jupyter 노트북에 파이썬에 대한 프로파일 사용 : towardsdatascience.com/speed-up-jupyter-notebooks-20716cbe2025
알렉세이 Martianov

72

항상가는 곳을 찾는 가장 간단 하고 빠른 방법입니다.

1. pip install snakeviz

2. python -m cProfile -o temp.dat <PROGRAM>.py

3. snakeviz temp.dat

브라우저에서 원형 차트를 그립니다. 가장 큰 부분은 문제 기능입니다. 매우 간단합니다.


1
이것은 매우 도움이되었습니다. 감사합니다.
jippyjoe4

55

나는 그 생각 cProfile하면서, 프로파일 링에 좋은 곳입니다 kcachegrind결과를 시각화에 좋은 곳입니다. pyprof2calltree핸들 사이의 파일 변환.

python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltree

필요한 도구를 설치하려면 (적어도 우분투에서) :

apt-get install kcachegrind
pip install pyprof2calltree

결과:

결과 스크린 샷


9
Mac 사용자는 설치 brew install qcachegrind각을 substitude kcachegrindqcachegrind 성공 프로파일에 대한 설명이다.
Kevin Katzke

나는 일에 그걸 얻기 위해이 작업을 수행했다 :export QT_X11_NO_MITSHM=1
Yonatan 심슨에게

41

GUI cProfile 덤프 뷰어 RunSnakeRun도 언급 할 가치가 있습니다. 있습니다. 정렬 및 선택을 통해 프로그램의 관련 부분을 확대 할 수 있습니다. 사진에서 직사각형의 크기는 촬영 시간에 비례합니다. 사각형 위로 마우스를 가져 가면 테이블 및지도의 모든 위치에서 해당 호출이 강조 표시됩니다. 사각형을 두 번 클릭하면 해당 부분이 확대됩니다. 해당 부분을 호출하는 사람과 해당 부분을 호출하는 사람이 표시됩니다.

설명 정보는 매우 유용합니다. 내장 라이브러리 호출을 처리 할 때 도움이 될 수있는 해당 비트에 대한 코드를 보여줍니다. 코드를 찾을 파일과 줄을 알려줍니다.

또한 OP가 '프로파일 링'이라고 말했지만 '타이밍'을 의미하는 것으로 보입니다. 프로파일 링하면 프로그램이 느리게 실행됩니다.

여기에 이미지 설명을 입력하십시오


34

좋은 프로파일 링 모듈은 line_profiler입니다 (kernprof.py 스크립트를 사용하여 호출). 여기에서 다운로드 할 수 있습니다 .

내 이해는 cProfile이 각 함수에 소비 된 총 시간에 대한 정보 만 제공한다는 것입니다. 따라서 개별 코드 줄은 시간이 지정되지 않습니다. 종종 한 줄에 많은 시간이 걸리기 때문에 과학 컴퓨팅에서는 문제가됩니다. 또한, 내가 기억하는 것처럼 cProfile은 numpy.dot에 쓰는 데 걸리는 시간을 포착하지 못했습니다.


34

최근 Python 런타임 및 가져 오기 프로파일을 시각화하기 위해 tuna 를 만들었습니다 . 이것은 여기에 도움이 될 수 있습니다.

여기에 이미지 설명을 입력하십시오

함께 설치

pip install tuna

런타임 프로파일 작성

python3 -m cProfile -o program.prof yourfile.py

또는 가져 오기 프로파일 (Python 3.7 이상 필요)

python3 -X importprofile yourfile.py 2> import.log

그런 다음 파일에서 tuna를 실행하십시오.

tuna program.prof

33

프로파일

line_profiler(이미 여기에 표시됨)도 영감을 받았으며 pprofile이는 다음과 같이 설명됩니다.

행 세분성, 스레드 인식 결정 및 통계 순수 파이썬 프로파일 러

이 도구는 라인 세분성을 제공하고 line_profiler순수 Python이며 독립형 명령 또는 모듈로 사용할 수 있으며으로 쉽게 분석 할 수있는 callgrind 형식 파일을 생성 할 수도 있습니다 [k|q]cachegrind.

vprof

다음 과 같이 설명되는 파이썬 패키지 인 vprof 도 있습니다 :

[...] 실행 시간 및 메모리 사용과 같은 다양한 Python 프로그램 특성에 대한 풍부하고 대화식 시각화를 제공합니다.

히트 맵


14

많은 훌륭한 답변이 있지만 결과를 프로파일 링 및 / 또는 정렬하기 위해 명령 줄이나 외부 프로그램을 사용합니다.

커맨드 라인을 만지거나 아무것도 설치하지 않고 IDE (eclipse-PyDev)에서 사용할 수있는 방법을 정말로 놓쳤습니다. 여기 있습니다.

명령 줄이없는 프로파일 링

def count():
    from math import sqrt
    for x in range(10**5):
        sqrt(x)

if __name__ == '__main__':
    import cProfile, pstats
    cProfile.run("count()", "{}.profile".format(__file__))
    s = pstats.Stats("{}.profile".format(__file__))
    s.strip_dirs()
    s.sort_stats("time").print_stats(10)

자세한 내용은 문서 또는 기타 답변을 참조하십시오.


예를 들어, 프로파일은 {map} 또는 {xxx}를 인쇄합니다. {xxx} 메소드가 어떤 파일에서 호출되는지 어떻게 알 수 있습니까? 내 프로필은 { 'zlib.Compress'objects의 'compress'방법 '인쇄) 대부분의 시간이 걸리지 만 zlib을 사용하지 않으므로 일부 호출 numpy 함수가 사용할 수 있습니다. 정확히 파일과 줄이 어느 것인지 어떻게 알 수 있습니까?
machen

12

멀티 스레드 코드에 대한 Joe Shaw의 대답이 예상대로 작동하지 않으면 runcallcProfile 의 메소드가 프로파일 링 된 함수 호출을 수행 self.enable()하고 self.disable()호출 하는 것으로 나타 났으 므로 직접 수행하고 원하는 코드를 가질 수 있습니다. 기존 코드와의 간섭을 최소화합니다.


3
훌륭한 팁! cprofile.py의 소스 코드를 살짝 들여다 보면 이것이 정확히 무엇인지 알 runcall()수 있습니다. 보다 구체적으로를 사용하여 프로파일 인스턴스를 만든 후 prof = cprofile.Profile()즉시 호출 prof.disable()한 다음 프로파일 링하려는 코드 섹션 주위에 추가 prof.enable()하고 prof.disable()호출하십시오.
martineau

이것은 매우 유용하지만 실제로 활성화와 비활성화 사이에있는 코드는 프로파일 링되지 않으며 호출하는 함수 만 프로파일 됩니다. 이 권리가 있습니까? print_stats ()의 숫자를 세려면 함수 호출에서 해당 코드를 래핑해야합니다.
Bob Stein

10

Virtaal의 소스 에는 프로파일 링 (특정 메소드 / 함수도)을 매우 쉽게 할 수있는 매우 유용한 클래스와 데코레이터가 있습니다. 그러면 KCacheGrind에서 출력을 매우 편안하게 볼 수 있습니다.


1
이 보석에 감사드립니다. 참고 : 이것은 모든 코드와 함께 독립형 모듈로 사용할 수 있으며 Virtaal 코드베이스는 필요하지 않습니다. 파일을 profiling.py에 저장하고 profile_func ()를 가져 오십시오. @profile_func ()를 프로파일 링하고 비올라해야하는 모든 함수의 데코레이터로 사용하십시오. :)
Amjith

9

cProfile은 빠른 프로파일 링에는 좋지만 대부분의 경우 오류로 인해 종료되었습니다. 함수 runctx는 환경과 변수를 올바르게 초기화하여이 문제를 해결합니다. 누군가에게 유용 할 수 있기를 바랍니다.

import cProfile
cProfile.runctx('foo()', None, locals())

7

누적 프로파일 러를 만들려면 함수를 연속으로 여러 번 실행하고 결과의 합계를 확인하십시오.

이것을 사용할 수 있습니다 cumulative_profiler 데코레이터 :

파이썬> = 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():
    ...

7

모든 멋진 UI가 설치 또는 실행되지 않는 경우 터미널 전용 (가장 간단한) 솔루션은 완전히
무시 cProfile하고로 대체하십시오. 이는 pyinstrument실행 직후 호출 트리를 수집하고 표시합니다.

설치:

$ pip install pyinstrument

프로필 및 표시 결과 :

$ python -m pyinstrument ./prog.py

python2 및 3에서 작동합니다.

[편집] 코드의 일부만 프로파일 링하기위한 API 문서는 여기 에서 찾을 수 있습니다 .


6

내 방법은 yappi ( https://github.com/sumerc/yappi ) 를 사용하는 것 입니다. 다음과 같은 방법으로 프로파일 링 정보를 시작, 중지 및 인쇄하는 메소드를 등록하는 RPC 서버와 결합하면 특히 유용합니다.

@staticmethod
def startProfiler():
    yappi.start()

@staticmethod
def stopProfiler():
    yappi.stop()

@staticmethod
def printProfiler():
    stats = yappi.get_stats(yappi.SORTTYPE_TTOT, yappi.SORTORDER_DESC, 20)
    statPrint = '\n'
    namesArr = [len(str(stat[0])) for stat in stats.func_stats]
    log.debug("namesArr %s", str(namesArr))
    maxNameLen = max(namesArr)
    log.debug("maxNameLen: %s", maxNameLen)

    for stat in stats.func_stats:
        nameAppendSpaces = [' ' for i in range(maxNameLen - len(stat[0]))]
        log.debug('nameAppendSpaces: %s', nameAppendSpaces)
        blankSpace = ''
        for space in nameAppendSpaces:
            blankSpace += space

        log.debug("adding spaces: %s", len(nameAppendSpaces))
        statPrint = statPrint + str(stat[0]) + blankSpace + " " + str(stat[1]).ljust(8) + "\t" + str(
            round(stat[2], 2)).ljust(8 - len(str(stat[2]))) + "\t" + str(round(stat[3], 2)) + "\n"

    log.log(1000, "\nname" + ''.ljust(maxNameLen - 4) + " ncall \tttot \ttsub")
    log.log(1000, statPrint)

그런 다음 프로그램이 작동하면 언제든지 startProfilerRPC 메소드 를 호출하여 프로파일 러를 시작하고 호출하여 프로파일 링 정보를 로그 파일에 덤프 printProfiler하거나 호출자에게 리턴하도록 rpc 메소드를 수정하여 해당 출력을 얻을 수 있습니다.

2014-02-19 16:32:24,128-|SVR-MAIN  |-(Thread-3   )-Level 1000: 
name                                                                                                                                      ncall     ttot    tsub
2014-02-19 16:32:24,128-|SVR-MAIN  |-(Thread-3   )-Level 1000: 
C:\Python27\lib\sched.py.run:80                                                                                                           22        0.11    0.05
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\xmlRpc.py.iterFnc:293                                                22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\serverMain.py.makeIteration:515                                                    22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\PicklingXMLRPC.py._dispatch:66                                       1         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.date_time_string:464                                                                                    1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py._get_raw_meminfo:243     4         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.decode_request_content:537                                                                          1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py.get_system_cpu_times:148 4         0.0     0.0
<string>.__new__:8                                                                                                                        220       0.0     0.0
C:\Python27\lib\socket.py.close:276                                                                                                       4         0.0     0.0
C:\Python27\lib\threading.py.__init__:558                                                                                                 1         0.0     0.0
<string>.__new__:8                                                                                                                        4         0.0     0.0
C:\Python27\lib\threading.py.notify:372                                                                                                   1         0.0     0.0
C:\Python27\lib\rfc822.py.getheader:285                                                                                                   4         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.handle_one_request:301                                                                                  1         0.0     0.0
C:\Python27\lib\xmlrpclib.py.end:816                                                                                                      3         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.do_POST:467                                                                                         1         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.is_rpc_path_valid:460                                                                               1         0.0     0.0
C:\Python27\lib\SocketServer.py.close_request:475                                                                                         1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\__init__.py.cpu_times:1066               4         0.0     0.0 

짧은 스크립트에는 그다지 유용하지 않지만 서버 유형 프로세스를 최적화하는 데 도움이됩니다. 특히이 printProfiler방법을 시간이 지남에 따라 여러 번 호출하여 다른 프로그램 사용 시나리오를 프로파일 링하고 비교할 수 있습니다.

최신 버전의 yappi에서는 다음 코드가 작동합니다.

@staticmethod
def printProfile():
    yappi.get_func_stats().print_all()

굉장한 Yappi로 이름을 지정해서는 안됩니까?
Therealstubot

불행히도 위의 코드는 pypy에서는 사용할 수없는 버전 0.62에서만 작동합니다. 모듈은 github.com/nirs/yappi/releases에서 사용할 수있는 0.62 소스에서 컴파일 하거나 해당 목적을 위해 저장소의 창을 위해 만든 빌드를 사용해야합니다. github.com/Girgitt/yappi/releases
씨 Girgitt

printProfiler 기능을 수정하여 최소한 1.0 이상의 인쇄 출력을 위해 버전 1.0과의 호환성을 쉽게 제공 할 수 있습니다. def printProfiler(): if not yappi_available: return stats = yappi.get_func_stats() stats.print_all(columns={0:("name",90), 1:("ncall", 5), 2:("tsub", 8), 3:("ttot", 8), 4:("tavg",8)}) (내가 포기한 주석에 코드 블록을 삽입하기 위해 몇 번 시도한 후에는 OK. 이것은 프로그래밍 중심의 Q & A 사이트에서는 믿을 수 없을 정도로 어렵습니다. )
Mr. Girgitt

4

Python에서 프로파일 링을 처리하는 새로운 도구는 PyVmMonitor입니다. http://www.pyvmmonitor.com/

그것은 같은 독특한 기능이 있습니다

  • 실행중인 (CPython) 프로그램에 프로파일 러 연결
  • Yappi 통합을 통한 온 디맨드 프로파일 링
  • 다른 머신의 프로파일
  • 다중 프로세스 지원 (멀티 프로세싱, 장고 ...)
  • 라이브 샘플링 / CPU보기 (시간 범위 선택)
  • cProfile / 프로파일 통합을 통한 결정적 프로파일 링
  • 기존 PStats 결과 분석
  • DOT 파일 열기
  • 프로그래밍 가능한 API 액세스
  • 방법 또는 라인별로 샘플 그룹화
  • PyDev 통합
  • PyCharm 통합

참고 : 상용이지만 오픈 소스 인 경우 무료입니다.


4

gprof2dot_magic

gprof2dotJupyterLab 또는 Jupyter Notebook에서 모든 Python 문을 DOT 그래프로 프로파일 링하는 마술 기능 .

여기에 이미지 설명을 입력하십시오

GitHub 저장소 : https://github.com/mattijn/gprof2dot_magic

설치

Python 패키지가 있는지 확인하십시오 gprof2dot_magic.

pip install gprof2dot_magic

그 의존성 gprof2dotgraphviz함께 설치됩니다

용법

매직 기능을 활성화하려면 먼저 gprof2dot_magic모듈을 로드하십시오

%load_ext gprof2dot_magic

그런 다음 라인 문장을 DOT 그래프로 프로파일하십시오.

%gprof2dot print('hello world')

여기에 이미지 설명을 입력하십시오


3

파이썬 스크립트가 무엇을하고 있는지 알고 싶습니까? 검사 쉘을 입력하십시오. Inspect Shell을 사용하면 실행중인 스크립트를 중단하지 않고 전역을 인쇄 / 변경하고 기능을 실행할 수 있습니다. 이제 자동 완성 및 명령 기록이 있습니다 (Linux에서만).

셸 검사는 pdb 스타일 디버거가 아닙니다.

https://github.com/amoffat/Inspect-Shell

그것을 사용할 수 있습니다 (그리고 손목 시계).



3

프로파일 링에서 보려는 내용에 따라 다릅니다. 간단한 시간 측정 항목은 (bash)로 제공 할 수 있습니다.

time python python_prog.py

'/ usr / bin / time'조차도 '--verbose'플래그를 사용하여 자세한 메트릭을 출력 할 수 있습니다.

각 함수가 제공하는 시간 메트릭을 확인하고 함수에 소요되는 시간을 더 잘 이해하기 위해 파이썬에서 내장 cProfile을 사용할 수 있습니다.

성능과 같은보다 자세한 지표로 들어가면 시간 만이 유일한 지표는 아닙니다. 메모리, 스레드 등에 대해 걱정할 수 있습니다.
프로파일 링 옵션 :
1. line_profiler 는 타이밍 메트릭을 라인 단위로 찾는 데 일반적으로 사용되는 또 다른 프로파일 러입니다.
2. memory_profiler 는 메모리 사용량을 프로파일 링하는 도구입니다.
3. heapy (프로젝트 Guppy에서) 힙의 오브젝트가 어떻게 사용되는지 프로파일하십시오.

이것들은 내가 사용하는 일반적인 것들 중 일부입니다. 그러나 더 자세한 내용을 알고 싶다면이 책을 읽어보십시오 . 성능을 염두에두고 시작하는 데 아주 좋은 책입니다. Cython 및 JIT (Just-in-Time) 컴파일 된 Python 사용에 대한 고급 주제로 이동할 수 있습니다.


2

austin 와 같은 통계 프로파일 러를 사용하면 계측이 필요하지 않으므로 간단히 다음과 같이 Python 응용 프로그램에서 프로파일 링 데이터를 얻을 수 있습니다.

austin python3 my_script.py

원시 출력은 그다지 유용하지 않지만 , 시간을 (마이크로 초 단위로 측정 된) 시간이 소비되는 곳의 내역을 제공하는 해당 데이터의 불꽃 그래프 표현을 얻기 위해 불꽃 을 graphgraph.pl 로 파이프 할 수 있습니다 .

austin python3 my_script.py | flamegraph.pl > my_script_profile.svg

1

통계 프로파일 러도 있습니다 statprof 있습니다. 샘플링 프로파일 러이므로 코드에 최소한의 오버 헤드를 추가하고 함수 기반이 아닌 라인 기반 타이밍을 제공합니다. 게임과 같은 부드러운 실시간 응용 프로그램에 더 적합하지만 cProfile보다 정확도가 떨어질 수 있습니다.

pypi버전 은 약간 오래되었으므로 git 저장소pip 를 지정 하여 설치할 수 있습니다 .

pip install git+git://github.com/bos/statprof.py@1a33eba91899afe17a8b752c6dfdec6f05dd0c01

다음과 같이 실행할 수 있습니다.

import statprof

with statprof.profile():
    my_questionable_function()

참조 https://stackoverflow.com/a/10333592/320036


1

방금 pypref_time에서 영감을 얻은 내 프로파일 러를 개발했습니다.

https://github.com/modaresimr/auto_profiler

데코레이터를 추가하면 시간이 많이 걸리는 기능 트리가 표시됩니다.

@Profiler(depth=4, on_disable=show)

Install by: pip install auto_profiler

import time # line number 1
import random

from auto_profiler import Profiler, Tree

def f1():
    mysleep(.6+random.random())

def mysleep(t):
    time.sleep(t)

def fact(i):
    f1()
    if(i==1):
        return 1
    return i*fact(i-1)


def show(p):
    print('Time   [Hits * PerHit] Function name [Called from] [Function Location]\n'+\
          '-----------------------------------------------------------------------')
    print(Tree(p.root, threshold=0.5))

@Profiler(depth=4, on_disable=show)
def main():
    for i in range(5):
        f1()

    fact(3)


if __name__ == '__main__':
    main()

출력 예


Time   [Hits * PerHit] Function name [Called from] [function location]
-----------------------------------------------------------------------
8.974s [1 * 8.974]  main  [auto-profiler/profiler.py:267]  [/test/t2.py:30]
├── 5.954s [5 * 1.191]  f1  [/test/t2.py:34]  [/test/t2.py:14]
   └── 5.954s [5 * 1.191]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
       └── 5.954s [5 * 1.191]  <time.sleep>
|
|
|   # The rest is for the example recursive function call fact
└── 3.020s [1 * 3.020]  fact  [/test/t2.py:36]  [/test/t2.py:20]
    ├── 0.849s [1 * 0.849]  f1  [/test/t2.py:21]  [/test/t2.py:14]
       └── 0.849s [1 * 0.849]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
           └── 0.849s [1 * 0.849]  <time.sleep>
    └── 2.171s [1 * 2.171]  fact  [/test/t2.py:24]  [/test/t2.py:20]
        ├── 1.552s [1 * 1.552]  f1  [/test/t2.py:21]  [/test/t2.py:14]
           └── 1.552s [1 * 1.552]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
        └── 0.619s [1 * 0.619]  fact  [/test/t2.py:24]  [/test/t2.py:20]
            └── 0.619s [1 * 0.619]  f1  [/test/t2.py:21]  [/test/t2.py:14]

0

서버에서 루트가 아닌 경우 lsprofcalltree.py를 사용하여 다음 과 같이 프로그램을 실행하십시오.

python lsprofcalltree.py -o callgrind.1 test.py

그런 다음 qcachegrind와 같은 callgrind 호환 소프트웨어로 보고서를 열 수 있습니다


0

IPython 노트북에서 코드 스 니펫에 대한 빠른 프로파일 통계를 가져옵니다. 노트북에 line_profiler 및 memory_profiler를 직접 내장 할 수 있습니다.

가져와!

!pip install line_profiler
!pip install memory_profiler

로드하세요!

%load_ext line_profiler
%load_ext memory_profiler

사용해!


%시각

%time print('Outputs CPU time,Wall Clock time') 
#CPU times: user 2 µs, sys: 0 ns, total: 2 µs Wall time: 5.96 µs

제공합니다 :

  • CPU 시간 : CPU 레벨 실행 시간
  • 시스템 시간 : 시스템 레벨 실행 시간
  • 합계 : CPU 시간 + 시스템 시간
  • 벽시계 : 벽시계 시간

% timeit

%timeit -r 7 -n 1000 print('Outputs execution time of the snippet') 
#1000 loops, best of 7: 7.46 ns per loop
  • 반복 횟수 (n)로 지정된 횟수의 런 (r) 중에서 최상의 시간을 제공합니다.
  • 시스템 캐싱에 대한 세부 사항을 출력합니다.
    • 코드 스 니펫이 여러 번 실행될 때 시스템은 몇 개의 opearation을 캐시하고 다시 실행하지 않아 프로파일 보고서의 정확성을 저해 할 수 있습니다.

정리

%prun -s cumulative 'Code to profile' 

제공합니다 :

  • 함수 호출 횟수 (ncalls)
  • 함수 호출마다 항목이 있습니다 (고유)
  • 통화 당 소요 시간 (percall)
  • 해당 함수 호출까지의 시간 (cumtime)
  • etc라는 함수 / 모듈의 이름 ...

누적 프로필


% 미트

%memit 'Code to profile'
#peak memory: 199.45 MiB, increment: 0.00 MiB

제공합니다 :

  • 메모리 사용량

% lprun

#Example function
def fun():
  for i in range(10):
    print(i)

#Usage: %lprun <name_of_the_function> function
%lprun -f fun fun()

제공합니다 :

  • 현명한 통계

라인 프로파일

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.