본격적으로 글을 적기전에 시간 측정을 위한 간단한 데코레이터를 먼저 하나 만들고 시작하겠다.
def check_time(func):
def wrapper(*args, **kwargs):
start = time.time()
check_func = func(*args, **kwargs)
total_time = time.time() - start
print(f'이 함수 {func.__name__} 를 실행하는데 {total_time}초가 걸렸습니다.')
return total_time
return wrapper
1. 상수는 한번만 연산하자.
상수는 한번만 연산하는 것이 좋다. for loop안에서 상수가 반복될 경우 속도가 느려질 수 있다.
@check_time
def for_inside_constant(constant: int):
empty = []
for i in range(10000000):
a = 3
empty.append(a*3)
print(empty[:5])
@check_time
def for_outside_constant(constant: int):
empty = []
a = 3
for i in range(10000000):
empty.append(a*3)
print(empty[:5])
for_inside_constant(3)
for_outside_constant(3)
위 두 함수를 비교해보자.
상수를 포문 밖에서 선언한 for_outside_constant가 조금 더 빠르다.
2. collection 모듈 활용하기
파이썬에는 collection 모듈이라는 것이 있다. collection 모듈 내부에는 여러 자료 구조들이 있는데, 이번 글에서는 예시로 OrderedDict에 대해서 다루어 보려고 한다. 말 그대로 dictionary를 정렬하여 반환하는 자료구조이다.
1. dictionary 생성후 정렬하는 방법
2. 처음부터 orderedDict로 생성하는 방법 두 가지를 비교해 볼 것이다.
1의 경우, 정렬 알고리즘에 따라서 속도 차이가 있을 수 있다는 점 참고 부탁드림..
@check_time
def sort_dict1(dict_array: dict):
dict_origin = {}
for i, j in zip(dict_array[0], dict_array[1]):
dict_origin[i] = j
sort_keys = sorted(dict_origin, key=dict_origin.get)
dict_with_sort = {}
for key in sort_keys:
dict_with_sort[key] = dict_origin[key]
return dict_with_sort
@check_time
def sort_dict2(dict_array: dict):
ordered_dict = OrderedDict()
for i, j in zip(dict_array[0], dict_array[1]):
ordered_dict[i] = j
return ordered_dict
sort_dict1(sample_data)
sort_dict2(sample_data)
OrderedDict로 생성했을 때가 조금 더 빠르다.
3. List Comprehension 이용하기
For loop를 이용하는 것 보다는 List Comprehension을 이용하는 것이 좀 더 빠르다.
@check_time
def for_list_comprehension(num: int):
return [i for i in range(num)]
@check_time
def for_just_loop(num: int):
temp_list = []
for i in range(num):
temp_list.append(i)
return temp_list
for_list_comprehension(1000000)
for_just_loop(1000000)
4. 빌트인 함수
빌트인 함수가 있는 경우 빌트인 함수를 사용하는 것이 더 좋다. max를 구하는 경우를 비교해보자. 빌트인 max와 직접 만든 max 함수 속도를 비교할 것이다. 직접 만든 max 함수의 경우 정렬해야 하는 상황을 가정하였다.
@check_time
def max_built(num_list):
print(max(num_list))
return max(num_list)
@check_time
def max_made(num_list):
print(sorted(num_list)[-1])
return sorted(num_list)[-1]
max_built(range(10000000, 0, -1))
max_made(range(10000000, 0, -1))
5. Numpy의 위대함
Numpy는 위대하다.. 왜냐하면, Numpy는 BroadCasting 연산을 지원하기 때문이다.
그 위력은 참으로, 강력하다고 할 수 있는데, 오른쪽은 (3, 3) 왼쪽은 (1, 3) 행렬이다. 이때, (1, 3) 행렬을 (3, 3) 구조에 맞게 확장시켜 연산을 가능하게 하는 것이 BroadCasting이다.
List의 경우 이러한 Broadcasting 기능이 없기 때문에 객체 내 원소 하나 하나 접근하여 값을 수정해야 한다.
@check_time
def list_calculation(num_list):
empty_list = []
for i in num_list:
empty_list.append(i*3)
return empty_list
@check_time
def numpy_calculation(num_list):
return np.array(num_list) * 3
list_calculation(range(100000000))
numpy_calculation(range(100000000))
역시, Numpy가 빠르다.. 갓넘파이
'딥상어동의 딥한 프로그래밍 > Python' 카테고리의 다른 글
[Python] 클래스와 상속 기초 예제 (0) | 2022.04.24 |
---|---|
[pytest] TDD, 초간단 pytest 실행해보기 (0) | 2022.04.17 |
[Python] PEP 8 스타일 가이드 중 헷갈리는 것 정리 (0) | 2022.04.11 |
[Python] Dot.점 의 의미 (0) | 2022.02.06 |
[Jupyter Notebook] 셀 넓이 설정, 다크 모드 (2) | 2021.09.26 |
제 블로그에 와주셔서 감사합니다! 다들 오늘 하루도 좋은 일 있으시길~~
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!