DoITgrow

[파이썬] 코드 동작 과정/속도를 비교하는 패키지 (feat. dis) 본문

프로그래밍

[파이썬] 코드 동작 과정/속도를 비교하는 패키지 (feat. dis)

김수성 (Kim SuSung) 2021. 11. 25. 21:17
반응형

안녕하세요.

오늘은 얼마전에 새로 알게되어 소개해드리고 싶은 패키지가 있어서 포스팅을 하네요.

아마 고수분들은 이미 알고 계시는 내용일 수 있겠지만 언제나 그랫든 저는 저와 같은 코린이 분들을 위해 기록을 남기는 중이라 의의가 있다고 생각합니다!!

원하는 결과를 얻기 위해 선택할 수 있는 다양한 방법이 있는데 어떤 것이 좋은거지?

직접 프로그래밍 언어를 개발하는 곳에 종사하지 않는한 파이썬에 기본 내장되어 있는 함수들의 작동 방식까지 깊게 배우지 않을 것 같아요. 다만 반복문을 2중, 3중, 그 이상 중첩해서 사용하면 속도가 기하급수적으로 느려진다는 것은 배웠고, 우리는 map 함수와 같은 병렬 처리를 통해 속도 저하를 피할 수 있다는 것은 많이 알고 있습니다. 

그런데 우리가 데이터 변수를 선언할 때 사용하는 댜앙햔 방식도 동작 원리가 조금씩 달라서속도 차이가 발생할 수 있다는 것은 아시나요? 물론 일반적인 데이터의 양으로는 데이터를 어떻게 선언하는지에 따라 발생하는 속도 차이를 사람이 느낄 수는 없을텐데요. 만약 언젠가 빅데이터를 만져야하고, 몇 억개 이상의 데이터를 메모리에 올려야 한다면 선언 방식을 바꿔서 더 조금이라도 최적화 시킬 수 있을 것 같습니다.

오늘 소개해드릴 패키지는 파이썬에 내장되어 있는 dis 패키지 인데요. Input, Output 값이 동일한 몇 개의 함수를 만들어 보셨다면 해당 패키지를 통해 어떤 함수가 더 효율적으로 처리되는지 비교해볼 수 있는 재밌는 패키지인 것 같네요.

데이터를 메모리에 올리는 과정 비교를 위한 딕셔너리 생성

# 딕셔너리 데이터를 만드는 방법1
dict1 = {'a': 'val1', 'b': 'val2'}

# 딕셔너리 데이터를 만드는 방법2
dict2 = dict(a=1, b=2)

# 딕셔너리 데이터를 만드는 방법3
dict3 = dict((a, 1), (b, 2))

▲  위와 같이 딕셔너리 데이터를 생성하면 모두 같은 결과를 얻을 수 있어요. 그런데 여기서 dis 패키지를 이용하면 각각의 데이터를 생성하는 과정을 비교해 볼 수 있습니다.

참고로 dis 패키지의 뜻은 dissassembly의 약어라고 하네요. 분해한다는 의미이니 함수의 실행 절차를 분해하는 것이라고 이해하면 되겠네요.

패키지 불러오기 및 데이터 생성 과정 비교

▼ 아래와 같이 dis 함수 안에 우리가 데이터를 생성하려 작성했던 코드를 문자열 형태로 감싸서 입력하면 코드가 실행되는 세부 절차를 출력합니다. dict1은 8스텝, dict는 10스텝, dict3은 16스텝이나 작동을 하네요. 이렇게 보면 차이가 정말 많이 나는 것 같기도 하네요!

from dis import dis

# dict1 생성 방법의 동작 과정
print(dis("{'a':1, 'b':2}"))
>>> 0 LOAD_CONST               0 (1)
>>> 2 LOAD_CONST               1 (2)
>>> 4 LOAD_CONST               2 (('a', 'b'))
>>> 6 BUILD_CONST_KEY_MAP      2
>>> 8 RETURN_VALUE


# dict2 생성 방법의 동작 과정
print(dis('dict(a=1, b=2)'))
>>> 0 LOAD_NAME                0 (dict)
>>> 2 LOAD_CONST               0 (1)
>>> 4 LOAD_CONST               1 (2)
>>> 6 LOAD_CONST               2 (('a', 'b'))
>>> 8 CALL_FUNCTION_KW         2
>>> 10 RETURN_VALUE


# dict3 생성 방법의 동작 과정
print(dis('dict((a, 1), (b, 2))'))
>>> 0 LOAD_NAME                0 (dict)
>>> 2 LOAD_NAME                1 (a)
>>> 4 LOAD_CONST               0 (1)
>>> 6 BUILD_TUPLE              2
>>> 8 LOAD_NAME                2 (b)
>>> 10 LOAD_CONST              1 (2)
>>> 12 BUILD_TUPLE             2
>>> 14 CALL_FUNCTION           2
>>> 16 RETURN_VALUE

마치며

위와 같이 데이터를 메모리에 올리는 간단한 코드 뿐만이 아니라 우리가 생성한 사용자 정의 함수도 dis 함수를 통해서 동작 과정을 살펴볼 수 있습니다. 여러가지 방식으로 만들었던 함수가 있다면 dis 함수를 돌려보고 효율적인 것을 사용해도 좋을 것 같아요. 허나 다른 한편으로 중요한 건 코드의 가독성일텐데요. 단지 속도가 좋다는 이유만으로 가독성이 나쁜 코드를 작성하는 것은 나중에 유지/보수가 힘들어질 것 같네요. 가독성과 효율성 2마리 토끼를 다 잡는 코드를 작성하는 실력이 길러질 때까지 열심히 공부해야겠습니다~~

반응형
Comments