Python/기타

[Python] 메모리 초과, 메모리 줄이기

Jong_seoung 2022. 10. 21. 00:51
반응형

메모리 초과, 메모리 줄이기

 

 

백준 파이썬 문제를 풀면서 분명 쉬운 문제이고 직접 돌려보았을 때에는 아무 문제없이 잘 작동되었고 값도 제대로 나왔는데 제출을 하면 자꾸 메모리 초과가 떴던 문제가 있는다.

 

그 문제를 풀면서 메모리를 줄일려고 for문의 개수를 줄이고 코드를 간략화하는 등 별 노력을 다 해보았는데도 결국 해결되지 않았고 검색을 통해서 해결을 하게 되었는데

 

우선 메모리 최적화를 진행하지 않고 무작정 프로그램이 잘 돌아간다고해서 그 코드가 마냥 좋은 코드라고 하기에는 부족하다. 결론적으로 파이썬의 메모리가 어떻게 구현되는지 알아보고 더 좋은 메모리 할당을 위한 좋은 습관을 들여주는 게 중요하다. 그래서 메모리 관련해서 정리를 하면서 이해를 하면 조금 더 좋을 것 같아 써 보려고 한다.

 


💡  파이썬의 메모리 할당

파이썬은 기본적으로 실행을 위해 메모리를 할당받을 때 파이썬 버전 및 환경 세팅에 의해 결정되고 불필요한 객체를 자동으로 삭제하기 때문에 별도로 관리해 줄 필요 없다.


 

💡  성능 향상과 메모리를 잘 쓰는 방법

대부분의 프로그래밍 언어가 느려지는 이유는 메모리 재할당이 이뤄지기 때문이다. 그리고 이러한 속도 저하는 for 문 안에서 자주 일어난다.

for i in a:
    a_list.append(i*2)

위 코드처럼 for문 안에서 a_list에 append를 할 경우 for문이 진행될 때마다 a_list에 append 하면서 메모리 재할당이 이뤄지기 때문에 속도 저하의 원인이 되고 메모리를 효율적으로 사용하지 못하는 경우가 나온다.

a = list(range(100))
a_list = map(lambda n: n*2, a)

하지만 위 코드처럼 map() 함수를 사용하면 파이썬 내부적으로 연산과 메모리를 관리하기 때문에 효율적으로 모든 요소에 원하는 계산 값을 넣을 수 있다. 

하지만 이 경우 바로 print(a_list)를 통해 결과 값을 얻으려고 할 경우 a_list의 메모리 주소가 뜨기 때문에 필자는 사용할 때는 map함수를 list로 감싸서 사용하였다. - 더 좋은 방법이 있는지 나중에 찾아보고 정리해봐야겠다.


 

💡 좋은 습관 들이기 

  • 파이썬의 알고리즘에 따라 효율적인 코딩 방식이 정해지는데 그 알고리즘을 공부하는 건 너무 힘들다. 하지만 메모리 관련 고민은 나 혼자 하고 있는 것이 아니고 아직 초보인 내가 접하는 데에는 무리가 있다고 판단이 되고 파이썬은 오픈소스가 많으니 효율적인 코드를 작성하는 방법에 대한 글들이 많다.

 

💯 제너레이터를 사용하라!

  • 제너 레이터는 아이템을 한 번에 리턴하는 것이 아니라 yield를 통해 하나씩 리턴해준다. 즉 큰 리스트를 검색할 때까 기다리지 않기 때문에 큰 리스트를 다룰 때 유용하게 사용할 수 있다.

 

💯 로컬 함수를 다시 선언하기

  • 파이썬은 글로벌 보다 로컬 변수가 빠르다. 그래서 함수를 로컬에 다시 정의하면 빠르게 이용할 수 있다.
def ex1():
    print("예제 1")

def ex2():
    p = print
    p("예제 2")

 

💯 구현되어 있는 함수나 라이브러리를 사용해라

  • 직접 코드를 하나하나 짜는 것도 좋지만 파이썬을 잘하는 분들이 만들어 놓은 라이브러리를 찾아 쓰는 것도 좋은 방법이다.

 

💯  intertools 이용하기

  • intertools를 이용하면 루프의 시간도 줄일 수 있고 읽기도 편하다.
  • intertools에 대해서는 조금 더 조사 후 내용을 추가해야 할 것 같다.
mylist=[]
for shape in [True, False]:
    for weight in (1, 5):
        firstlist=firstlist+function(shape, weight)

같은 코드 :

from itertools import product, chain
list(chain.from_iterable(function(shape, weight) for weight, 
shape in product([True, False], range(1, 5))))

 

 

 


참고 글 : https://yomangstartup.tistory.com/105https://wikidocs.net/21057

반응형