27. # gevent-example.py
import gevent
def slower():
for x in range(4):
for y in range(10000000): pass
gevent.sleep(0)
def faster():
for x in range(2):
for y in range(10000000): pass
gevent.sleep(0)
gevent.spawn(slower)
gevent.spawn(faster)
gevent.wait()
Py https://github.com/sublee/pyconkr2015-profiling-resources/blob/master/gevent_example.py
37. Clock type: CPU
Ordered by: totaltime, desc
name ncall tsub ttot tavg
script.py:1 <module> 1 0.000018 1.815449 1.815449
script.py:4 foo 2 0.288737 1.815422 0.907711
script.py:14 bar 1 0.000004 1.001799 1.001799
script.py:10 baz 1 0.000005 0.813632 0.813632
name tid ttot scnt
_MainThread 139638664439616 1.816491 1
38. Clock type: CPU
Ordered by: totaltime, desc
name ncall tsub ttot tavg
script.py:1 <module> 1 0.000018 1.815449 1.815449
script.py:4 foo 2 0.288737 1.815422 0.907711
script.py:14 bar 1 0.000004 1.001799 1.001799
script.py:10 baz 1 0.000005 0.813632 0.813632
name tid ttot scnt
_MainThread 139638664439616 1.816491 1
Exclusive Inclusive
39. # gevent-example.py
import gevent
def slower():
for x in range(4):
for y in range(10000000): pass
gevent.sleep(0)
def faster():
for x in range(2):
for y in range(10000000): pass
gevent.sleep(0)
gevent.spawn(slower)
gevent.spawn(faster)
gevent.wait()
slower < faster
(약 2배)
Py https://github.com/sublee/pyconkr2015-profiling-resources/blob/master/gevent_example.py
61. def spin(sec):
f (<frame of spin>, 'call', ...)
t = time.time()
while time.time() - t < sec:
pass
f (<frame of spin>, 'return', ...)
def spin5():
f (<frame of spin5>, 'call', ...)
spin(5)
f (<frame of spin5>, 'return', ...)
68. # gevent-example.py
import gevent
def slower():
for x in range(4):
for y in range(10000000): pass
gevent.sleep(0)
def faster():
for x in range(2):
for y in range(10000000): pass
gevent.sleep(0)
gevent.spawn(slower)
gevent.spawn(faster)
gevent.wait()
slower < faster
(약 2배)
Py https://github.com/sublee/pyconkr2015-profiling-resources/blob/master/gevent_example.py
70. slowerHub faster
f ('switch', (Hub, slower))
f ('switch', (slower, Hub))
f ('switch', (Hub, faster))
f ('switch', (faster, Hub))
f ('switch', (Hub, slower))
85. def f(): pass
def shallow(n):
for x in range(n):
f()
def deep(n):
if n != 0:
deep(n - 1)
Py https://github.com/sublee/pyconkr2015-profiling-resources/blob/master/subcalls_example.py
86. def f(): pass
def shallow(n):
for x in range(n):
f()
def deep(n):
if n != 0:
deep(n - 1)
87. def f(): pass
def shallow(n):
for x in range(n):
f()
def deep(n):
if n != 0:
deep(n - 1)
91. 이벤트 기반 프로파일링
• 실행 시간, 호출 횟수 측정
• 이벤트 전수 조사
e.g. profile, hotshot, Yappi, line_profiler
통계적 프로파일링
• 상대적 실행 빈도 측정
• 표본 조사
e.g. pyinstrument, plop, pprofile
92. 통계적 프로파일링
• 샘플링 할 때 실행 중이던 콜스택을 조사
• Exclusive Count ― 콜스택 말단이던 횟수
• Inclusive Count ― 콜스택에 속했던 횟수
93. def spin(sec):
t = time.time()
while time.time() - t < sec:
pass
def spin5():
spin(5)
spin5()
Py https://github.com/sublee/pyconkr2015-profiling-resources/blob/master/spin_example.py
113. # facweb.py
from flask import Flask
app = Flask(__name__)
@app.route('/<int:n>')
def fac(n):
r = 1
for x in range(2, n + 1):
r *= x
return str(r)
app.run(port=8080)
Py https://github.com/sublee/pyconkr2015-profiling-resources/blob/master/facweb.py
126. 그밖에
• <Profiling (computer programming)>
Wikipedia • http://goo.gl/qeblxo
• <What are Exclusive and Inclusive?>
Steve Carroll • http://goo.gl/KCysud
• <What are Exclusive and Inclusive?>
Steve Carroll • http://goo.gl/KCysud
• <Beginners Guide to Performance Profiling>
MSDN • https://goo.gl/f9Oej9
• <Profiling tools>
Alain Leufroy • https://goo.gl/YxcVWF
129. 실시간으로 프로파일링 할 때
갱신주기 내 함수 호출만 측정되나요?
네, 현재는 그렇습니다. 분명 갱신주기와 측정주기가 같아서 불편한
경우가 있는데요, Unity3D 프로파일러처럼 실시간 분석결과뿐 아니
라 과거의 분석결과도 탐색할 수 있게 해 해소할 계획입니다.
Q.
A.
130. 개발하는 데 얼마나 걸렸나요?
2014년 8월 한 달 동안 TracingProfiler와 뷰어, 서버를 만들
었고, 2015년 6월부터 천천히 두 달, 집중적으로 한 달 동안
SamplingProfiler를 만들었습니다.
Q.
A.
131. Python 3의 asyncio와 호환되나요?
https://github.com/what-studio/profiling/issues/26
해당 이슈가 올라와 있지만, 아직 확인해보지 못했습니다.
Q.
A.
132. 분석결과에서 특정 함수를 필터링할 수 있나요?
https://github.com/what-studio/profiling/issues/30
지금은 불가능하지만 마침 제안받은 게 있어 구현할 예정입니다.
Q.
A.
133. C 함수도 분석할 수 있나요?
sys.setprofile의 콜백함수에 C 함수 호출과 반환 이벤트도
c_call, c_return이라는 이름으로 들어옵니다. 따라서 분석할
수 있겠으나 C 함수 실행에 대응하는 파이썬 frame이 없다 보니 다
소 번거로운 점이 있어 미뤄뒀습니다. 현재 TracingProfiler는
C 함수 이벤트를 무시합니다.
파이썬 frame만 조사할 수 있는 SamplingProfiler의 경우 C
함수는 분석하지 못할 것 같습니다.
Q.
A.
134. deferral 유틸리티를 어디엔 썼고
어디엔 안 썼던데 이유가 무엇인가요?
현장에선 Profiler 객체를 with 문에 넣기도 하고 안 넣기도 하
는 이유가 무엇이냐는 질문으로 오해하고, 그 기능이 처음부터 의도한
게 아니라 풀 리퀘스트로 받은 것이라 그런 것 같다고 잘 못 답변 드렸
습니다.
deferral 유틸리티는 with 문이나 try-finally 문이 깊어지
는 게 싫어서 만들었습니다. 필요한 곳에 모두 쓸 것을 의도했으나 실
수로 빼먹은 것 같습니다.
Q.
A.
135. 프로파일러를 프로파일링할 수 있나요?
TracingProfiler 자체의 성능을 분석하기 위해 썼던 방법입니
다.
우선 전달받은 호출/반환 이벤트를 모두 기록해 목록화하는 함수를
sys.setprofile에 등록한 후 예제코드를 실행합니다. 그렇게
모인 이벤트들에 대해 TracingProfiler._profile() 메소
드를 직접 호출하는 코드를 만들고 그걸 프로파일링했습니다.
Q.
A.