파이썬 내장함수로 존재하는 cProfile은 CSI처럼 파이썬 코드에 작성된 '함수'를 추적하는 '함수'입니다.
사용법은 간단합니다.
# import 하신 후에
import cProfile
# 테스팅할 함수를 작성하고
def test_cProfile(a):
return a+10
# cProfile.run([함수명]) 형식으로 함수를 실행시킵니다.
cProfile.run('test_cProfile(10)')
# 결과
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 craw.py:64(test_cProfile)
1 0.000 0.000 0.000 0.000 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
결과에 나온 항목을 뜯어봅시다.
ncalls(호출횟수)
tottime(총시간)
cumtime(누적시간)
percall(시간 별 호출수)
filename:lineno(function):
리스트컴프리헨션과 리스트어펜드를 cProfile을 사용해 비교해봅시다.
range를 활용해 1억번 연산을 해봅시다.
def test_list_comprehension(x):
result = [i for i in range(x)]
return result
def test_list_append(x):
result = []
for i in range(x):
result.append(i)
return result
cProfile.run('test_list_comprehension(100000000)')
cProfile.run('test_list_append(100000000)')
5 function calls in 9.635 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 3.308 3.308 9.635 9.635 <string>:1(<module>)
1 0.000 0.000 6.327 6.327 craw.py:64(test_list_comprehension)
1 6.327 6.327 6.327 6.327 craw.py:65(<listcomp>)
1 0.000 0.000 9.635 9.635 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
100000004 function calls in 22.610 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 3.184 3.184 22.609 22.609 <string>:1(<module>)
1 13.143 13.143 19.426 19.426 craw.py:69(test_list_append)
1 0.000 0.000 22.610 22.610 {built-in method builtins.exec}
100000000 6.283 0.000 6.283 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
9초 vs 22초로 리스트 컴프리헨션의 압승으로 나왔습니다.
결정적인 포인트는 함수 호출횟수입니다. 컴프리헨션 함수를 딱 한번 사용하는 리스트 컴프리헨션 표현식과 달리 append방식은 append내장함수를 1억번이나 호출했고 이에따라 2.5배 가까이 느리게 리스트가 생성되었습니다.
파이썬에선 왜 Pythonic하게 코드를 작성해야되는지, 대표적인 Pythonic한 Expression인 ListComprehension의 효율성을 통해 알아 볼 수 있었습니다.