일반적으로 쉘 명령을 사용 time
합니다. 내 목적은 데이터가 작은, 중간, 큰 또는 매우 큰 집합인지, 얼마나 많은 시간과 메모리 사용량이 될지 테스트하는 것입니다.
이 작업을 수행하는 Linux 용 도구 또는 Python 용 도구가 있습니까?
답변:
한 번 봐 가지고 timeit , 파이썬 프로파일 및 pycallgraph을 . 또한 " SnakeViz " 를nikicc
언급 하여 아래 주석 을 확인하십시오 . 유용한 프로파일 링 데이터의 또 다른 시각화를 제공합니다.
def test():
"""Stupid test function"""
lst = []
for i in range(100):
lst.append(i)
if __name__ == '__main__':
import timeit
print(timeit.timeit("test()", setup="from __main__ import test"))
# For Python>=3.5 one can also write:
print(timeit.timeit("test()", globals=locals()))
기본적으로 Python 코드를 문자열 매개 변수로 전달할 수 있으며 지정된 시간에 실행되고 실행 시간을 인쇄합니다. 문서 의 중요한 부분 :
timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None)
Timer
주어진 문, 설정 코드 및 타이머 함수 로 인스턴스를 만들고 숫자 실행 으로timeit
메서드를 실행합니다. 선택적 globals 인수는 코드를 실행할 네임 스페이스를 지정합니다.
... 그리고 :
Timer.timeit(number=1000000)
시간 수 주 문 실행. 이것은 setup 문을 한 번 실행 한 다음 기본 문을 여러 번 실행하는 데 걸리는 시간 (초 단위로 측정)을 float로 반환합니다. 인수는 루프를 통과하는 횟수이며 기본값은 백만입니다. 기본 문, 설정 문 및 사용할 타이머 함수가 생성자에 전달됩니다.참고 : 기본적
timeit
으로garbage collection
타이밍 동안 일시적으로 꺼집니다 . 이 접근 방식의 장점은 독립적 인 타이밍을 더 비슷하게 만든다는 것입니다. 이 단점은 GC가 측정되는 기능의 성능에 중요한 구성 요소가 될 수 있다는 것입니다. 그렇다면 GC를 설정 문자열 의 첫 번째 문으로 다시 활성화 할 수 있습니다 . 예를 들면 :
timeit.Timer('for i in xrange(10): oct(i)', 'gc.enable()').timeit()
프로파일 링은 무슨 일이 일어나고 있는지에 대한 훨씬 더 자세한 아이디어 를 제공합니다 . 다음 은 공식 문서 의 "인스턴트 예제"입니다 .
import cProfile
import re
cProfile.run('re.compile("foo|bar")')
당신에게 줄 것 :
197 function calls (192 primitive calls) in 0.002 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.001 0.001 <string>:1(<module>)
1 0.000 0.000 0.001 0.001 re.py:212(compile)
1 0.000 0.000 0.001 0.001 re.py:268(_compile)
1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset)
1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset)
4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction)
3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile)
이 두 모듈 모두 병목 지점을 찾을 수있는 위치에 대한 아이디어를 제공해야합니다.
또한의 출력을 이해하려면 이 게시물을profile
살펴보십시오.
NOTE pycallgraph는 2018 년 2 월부터 공식적으로 폐기되었습니다 . 2020 년 12 월 현재 Python 3.6에서는 여전히 작업 중이었습니다. 파이썬이 프로파일 링 API를 노출하는 방법에 핵심적인 변경 사항이없는 한 유용한 도구로 남아 있어야합니다.
이 모듈 은 graphviz를 사용하여 다음과 같은 콜 그래프를 만듭니다.
색상별로 가장 많이 사용한 경로를 쉽게 확인할 수 있습니다. pycallgraph API를 사용하거나 패키지화 된 스크립트를 사용하여 만들 수 있습니다.
pycallgraph graphviz -- ./mypythonscript.py
그러나 오버 헤드는 상당히 상당합니다. 따라서 이미 오래 실행되는 프로세스의 경우 그래프를 만드는 데 시간이 걸릴 수 있습니다.
나는 간단한 데코레이터를 사용하여
def st_time(func):
"""
st decorator to calculate the total time of a func
"""
def st_func(*args, **keyArgs):
t1 = time.time()
r = func(*args, **keyArgs)
t2 = time.time()
print "Function=%s, Time=%s" % (func.__name__, t2 - t1)
return r
return st_func
timeit
내가 쓴 있도록 모듈은 느리고 이상한 :
def timereps(reps, func):
from time import time
start = time()
for i in range(0, reps):
func()
end = time()
return (end - start) / reps
예:
import os
listdir_time = timereps(10000, lambda: os.listdir('/'))
print "python can do %d os.listdir('/') per second" % (1 / listdir_time)
나를 위해 그것은 말한다 :
python can do 40925 os.listdir('/') per second
이것은 원시적 인 종류의 벤치마킹이지만 충분합니다.
나는 보통 time ./script.py
얼마나 걸리는지 빨리 확인합니다. 그래도 메모리는 표시되지 않지만 적어도 기본값은 아닙니다. /usr/bin/time -v ./script.py
메모리 사용량을 포함하여 많은 정보를 얻는 데 사용할 수 있습니다 .
/usr/bin/time
과 -v
옵션이 많은 배포판에서 기본적으로 사용할 수 없습니다, 설치해야합니다. sudo apt-get install time
등 데비안, 우분투에서 pacman -S time
아치 리눅스
모든 메모리 요구 사항을위한 메모리 프로파일 러.
https://pypi.python.org/pypi/memory_profiler
pip 설치를 실행합니다.
pip install memory_profiler
라이브러리 가져 오기 :
import memory_profiler
프로파일 링하려는 항목에 데코레이터를 추가합니다.
@profile
def my_func():
a = [1] * (10 ** 6)
b = [2] * (2 * 10 ** 7)
del b
return a
if __name__ == '__main__':
my_func()
코드를 실행하십시오.
python -m memory_profiler example.py
출력 받기 :
Line # Mem usage Increment Line Contents
==============================================
3 @profile
4 5.97 MB 0.00 MB def my_func():
5 13.61 MB 7.64 MB a = [1] * (10 ** 6)
6 166.20 MB 152.59 MB b = [2] * (2 * 10 ** 7)
7 13.61 MB -152.59 MB del b
8 13.61 MB 0.00 MB return a
예제는 위에 링크 된 문서의 것입니다.
nose 와 플러그인 중 하나 , 특히이 플러그인을 살펴보십시오 .
일단 설치되면 nose는 경로에있는 스크립트이며 일부 Python 스크립트가 포함 된 디렉토리에서 호출 할 수 있습니다.
$: nosetests
이것은 현재 디렉토리의 모든 파이썬 파일을 살펴보고 테스트로 인식하는 모든 함수를 실행합니다. 예를 들어 이름에 test_라는 단어가있는 모든 함수를 테스트로 인식합니다.
따라서 test_yourfunction.py라는 파이썬 스크립트를 생성하고 다음과 같이 작성할 수 있습니다.
$: cat > test_yourfunction.py
def test_smallinput():
yourfunction(smallinput)
def test_mediuminput():
yourfunction(mediuminput)
def test_largeinput():
yourfunction(largeinput)
그런 다음 실행해야
$: nosetest --with-profile --profile-stats-file yourstatsprofile.prof testyourfunction.py
프로필 파일을 읽으려면 다음 파이썬 줄을 사용하십시오.
python -c "import hotshot.stats ; stats = hotshot.stats.load('yourstatsprofile.prof') ; stats.sort_stats('time', 'calls') ; stats.print_stats(200)"
nose
핫샷에 의존합니다. 그것은 더 이상 파이썬 2.5 이후 유지되지 것 만 "전문적인 사용을 위해"유지
timeit
매우 느리다는 점에 주의하세요. 중간 프로세서에서 초기화 (또는 함수 실행)하는 데 12 초가 걸립니다. 이 대답을 테스트 할 수 있습니다.
def test():
lst = []
for i in range(100):
lst.append(i)
if __name__ == '__main__':
import timeit
print(timeit.timeit("test()", setup="from __main__ import test")) # 12 second
time
대신 사용하겠습니다 . 내 PC에서 결과를 반환합니다.0.0
import time
def test():
lst = []
for i in range(100):
lst.append(i)
t1 = time.time()
test()
result = time.time() - t1
print(result) # 0.000000xxxx
timeit
노이즈를 평균화하기 위해 함수를 여러 번 실행합니다 . 반복 횟수는 옵션 입니다. Python에서 런타임 벤치마킹 또는이 질문에 대한 승인 된 답변의 뒷부분을 참조 하세요.
snakeviz
cProfile 용 대화 형 뷰어
https://github.com/jiffyclub/snakeviz/
cProfile은 https://stackoverflow.com/a/1593034/895245 에 언급 되었고 snakeviz는 댓글에 언급 되었지만 더 강조하고 싶었습니다.
cprofile
/ pstats
출력 을 보는 것만으로 프로그램 성능을 디버깅하는 것은 매우 어렵습니다 . 왜냐하면 기능 당 총 시간 만 사용할 수 있기 때문입니다.
그러나 일반적으로 실제로 필요한 것은 각 호출의 스택 추적이 포함 된 중첩 된 뷰를 확인하여 실제로 주요 병목 현상을 쉽게 찾는 것입니다.
그리고 이것은 snakeviz가 기본 "고드름"보기를 통해 제공하는 것입니다.
먼저 cProfile 데이터를 바이너리 파일로 덤프 한 다음 그에 대해 snakeviz 할 수 있습니다.
pip install -u snakeviz
python -m cProfile -o results.prof myscript.py
snakeviz results.prof
이렇게하면 브라우저에서 열 수있는 stdout에 대한 URL이 인쇄되며, 여기에는 다음과 같은 원하는 출력이 포함됩니다.
그런 다음 다음을 수행 할 수 있습니다.
프로필 지향 질문 : Python 스크립트를 어떻게 프로파일 링 할 수 있습니까?
당신이 timeit에 대한 상용구 코드를 작성하고 결과를 분석하기 쉬운 싶어하지 않는 경우, 한 번 봐 걸릴 benchmarkit을 . 또한 이전 실행 이력을 저장하므로 개발 과정에서 동일한 기능을 쉽게 비교할 수 있습니다.
# pip install benchmarkit
from benchmarkit import benchmark, benchmark_run
N = 10000
seq_list = list(range(N))
seq_set = set(range(N))
SAVE_PATH = '/tmp/benchmark_time.jsonl'
@benchmark(num_iters=100, save_params=True)
def search_in_list(num_items=N):
return num_items - 1 in seq_list
@benchmark(num_iters=100, save_params=True)
def search_in_set(num_items=N):
return num_items - 1 in seq_set
benchmark_results = benchmark_run(
[search_in_list, search_in_set],
SAVE_PATH,
comment='initial benchmark search',
)
터미널에 인쇄하고 마지막 실행 데이터와 함께 사전 목록을 반환합니다. 명령 줄 진입 점도 사용할 수 있습니다.
변경 N=1000000
하고 다시 실행하면
python -m cProfile -o results.prof myscript.py
. oputput 파일은 다음 아주 멋지게 프로그램에 의해 브라우저에 표시 할 수있다라는 SnakeViz가 사용snakeviz results.prof