반응형
기존의 코드를 리펙토링 하면서 여러 가지 방법을 써보며 성능테스트를 하면서
가독성과 간결성, 성능을 비교하며 테스트하였습니다.
1. example_1
# 첫번째 방법
start_time = time.time()
list_first_uid: list[int] = []
list_second_uid: list[int] = []
dict_number: dict[int, int] = {}
for i in range(10000000):
list_first_uid.append(i)
list_second_uid.append(i)
dict_number[i] = i
end_time = time.time()
print(f"First method took {end_time - start_time} seconds")
2. example_2
# 두번째 방법
start_time = time.time()
list_first_uid, list_second_uid, tuple_dict_number = zip(*((i, i, (i, i)) for i in range(10000000)))
dict_number = dict(tuple_dict_number)
end_time = time.time()
print(f"Second method took {end_time - start_time} seconds")
이렇게 2가지 방식이 있습니다.
다른 방식도 있으나, 대표적으로 고민했던 로직이 이렇게 2가지였습니다.
비교를 하면 두 번째 방식(example_2)이 간결해 보이고 깔끔해 보이는(?) 느낌이 있습니다.
한 줄로 눈에 확 들어오기도 합니다.
예시이기 때문에 10,000,000의 숫자를 for문을 통하여 2개의 list와 1개의 dict에 삽입하는 테스트를 하였습니다.
개인적 생각으로는 두 번째 방식(example_2)이 더 깔끔하여 보이지만,
성능상에서는 큰 차이가 있습니다.
Result
First method took 3.508805751800537 seconds
Second method took 33.76016187667847 seconds
테스트 방식에 따라 다르지만, 동일한 상황에서 동일한 행동을 하였을 때,
성능 차이가 약 1.1~1.2배 정도 차이가 났습니다.
왜 이런 성능 차이가 나는가? 라는 것에 의문이 들 겁니다. (아마..?)
1. 튜플 생성 및 언패킹 오버헤드:
- 두 번째 방법에서는 (i, i, (i, i)) 형태로 각 루프마다 튜플을 생성하고, zip 함수가 이를 언패킹하여 각 리스트에 분리하는 과정이 있습니다. 튜플 생성과 언패킹은 추가적인 메모리 할당과 연산을 필요로 하여 시간 소요가 큽니다.
2. 리스트 생성과 변환 오버헤드:
- zip 함수는 튜플로 결과를 반환하므로, 마지막에 이를 리스트로 변환해야 합니다. list(list_first_uid)와 같은 변환은 1000만 개의 요소를 가진 튜플을 리스트로 변환하기 때문에 시간이 많이 소요됩니다.
3. 동시 처리의 비효율성:
- 첫 번째 방법은 단순히 리스트와 사전을 동시에 업데이트합니다. 각 append와 사전 할당 연산이 독립적으로 일어나고, 이 과정은 파이썬 인터프리터에서 매우 최적화되어 있습니다.
- 두 번째 방법은 제너레이터 표현식을 사용하여 1000만 개의 튜플을 생성하고, 이를 zip 함수로 한 번에 처리하려고 합니다. 이 과정에서 많은 메모리 사용과 CPU 오버헤드가 발생합니다.
zip이 병렬 처리가 가능하다는 점에서 굉장히 많은 강점이 있다고 생각할 수도 있으나,
막상 성능 테스트를 통하여 확인하였을 때,
그 값을 활용해야 한다면 오버헤드가 발생하여 성능상 떨어질 수도 있다는 단점이 있습니다.
상황에 따라 다 다르기 때문에 무조건 나쁘다고 이야기할 수는 없지만,
가독성과 간결성이냐 성능이냐에 따라 선택할 수 있을 것 같습니다.
반응형
'Python' 카테고리의 다른 글
[Python] Fast API에 대해 알아보기 (0) | 2023.04.26 |
---|---|
[Python] 웹 크롤링vs웹 스크래핑 (0) | 2021.06.30 |
[Python] 파이썬의 가장 대표적인 패키지들 (0) | 2021.06.29 |
[Python] 스탠다드 라이브러리 vs 외부 라이브러리 (0) | 2021.06.28 |
[Python]__init__파일 (0) | 2021.06.25 |