파이썬 프로그래밍에서 가장 경제적인 메모리 사용량을 파악하는 작업은 다재다능한 메모리 특성으로 인해 종종 어려움을 겪습니다. 이러한 상황에서는 메모리 프로파일러를 활용하는 것이 효과적인 해결책이 될 수 있습니다. 누수를 감지하는 것 외에도 코드의 메모리 프로파일을 모니터링하면 메모리의 효율적인 사용에 관한 귀중한 인사이트를 얻을 수 있습니다.

Python을 사용하여 머신 러닝 모델이나 웹 애플리케이션을 만들 때 스크립트, 특정 코드 줄 또는 함수와 같은 다양한 요소에 대한 메모리 사용량 프로필을 추정할 수 있습니다.

파이썬에서 메모리 프로필을 추정하는 몇 가지 도구

잠재적인 성능 제한으로 인해 전체 코드베이스의 전체 메모리 프로필을 추정하는 것은 비실용적일 수 있습니다. 보다 효과적인 접근 방식은 과도한 메모리 사용량이 의심되는 특정 함수나 메서드를 선택적으로 분석하는 것입니다. 그러나 포괄적인 분석이 필요한 경우에는 애플리케이션 내에 이러한 작업을 처리하도록 특별히 설계된 별도의 모듈을 지정하는 것이 유용할 수 있습니다.

Python 프로그래밍 언어에는 여러 가지 프로파일링 라이브러리가 존재하며, 그 중 널리 사용되는 라이브러리로는 memory\_profiler, psutil, Tracemalloc, pympler 등이 있습니다. 이 튜토리얼에서는 메모리\_프로파일러와 psutil의 활용에 중점을 두겠습니다.

메모리 사용률은 특히 메서드나 함수의 실행으로 인한 전체 소비량과 관련하여 psutil을 통해 정확하게 추정할 수 있습니다. 그러나 memory\_profiler는 일정 기간 동안의 라인별 및 기능별 할당 내역에 관한 훨씬 더 포괄적인 데이터를 제공합니다.

psutil 설치도 포함되므로 Python 가상 환경에 memory\_profiler를 설치하세요.

 pip install memory_profiler

메모리에서 객체 크기 가져오기

메모리 프로파일링을 시작하려면 먼저 RAM 내에 할당할 데이터 엔티티의 크기를 결정해야 합니다.

소프트웨어 개발 프로세스를 시작할 때 이러한 형태의 프로파일링은 프로그램 내에서 사용할 가장 적합한 객체 유형을 식별하는 데 효과적인 도구로 사용됩니다.

최적의 Python 데이터 유형 선택과 같이 특정 목적을 달성하는 데 필요한 기술 선택과 관련하여 불확실성이 발생하는 경우, 각 옵션의 바이트 크기를 평가하여 특정 목적에 더 나은 확장성을 제공하는 옵션이 무엇인지 결정할 수 있습니다.

이 글도 확인해 보세요:  HTTP와 HTTPS: 차이점은 무엇인가요?

내장 함수인 sys.getsizeof()를 활용하면 이러한 맥락에서 유용하게 사용할 수 있습니다.

 import sys
print(f"list size: {sys.getsizeof([])} bytes")
print(f"dictionary size: {sys.getsizeof(dict)} bytes")
print(f"tuple size: {sys.getsizeof(())} bytes")
print(f"set size: {sys.getsizeof({})} bytes")

시장 동향, 소비자 선호도 등 다양한 요소를 종합적으로 분석한 결과, 이번 신제품 도입이 전체 매출에 긍정적인 영향을 미칠 것으로 판단되었습니다.

`sys.getsizeof()` 메서드를 활용하여 내재 함수와 사용자 정의 함수의 메모리 사용량을 대조할 수 있습니다.

파이썬 포 루프를 사용하는 사용자 정의 길이 함수를 살펴보고 대조해 보겠습니다.

 import sys

def getLength(iterable):
    count = 0

    for i in iterable:
        count +=1

    return count

print(f"Built-in length function: {sys.getsizeof(len)} bytes")
print(f"Custom length function: {sys.getsizeof(getLength)} bytes")

제공된 코드를 실행하면 다음과 같은 결과가 생성됩니다:

외부 참조를 고려하지 않고 객체의 본질적인 정보만 포함하므로 엔티티의 크기를 평가하는 데 sys.getsizeof를 활용하는 것은 제한적입니다. 개체가 미치는 영향의 정도를 종합적으로 평가하려면 프로파일링에 대한 보다 전문적인 접근 방식이 필요합니다.

파이썬 함수의 메모리 프로파일 찾기

memory\_profiler 라이브러리를 활용하면 지정된 함수 내의 각 개별 코드 줄에 대한 복잡한 메모리 프로파일을 획득할 수 있습니다. 이는 원하는 함수 또는 메서드에 `@profile` 데코레이터를 적용하여 수행할 수 있습니다.

 import pandas
import numpy
from memory_profiler import profile

class Manipulate:
    @profile
    def manipulateData(self):
        df = pandas.DataFrame({
            'A' :[0, 3, numpy.nan, 10, 3, numpy.nan],
            'B' : [numpy.nan, "Pandas", numpy.nan, "Pandas", "Python", "JavaScript"],
        })

        df.fillna(method='bfill', inplace=True)
        df.fillna(method='ffill', inplace=True)
        return str(df)

manip = Manipulate()
print(manip.manipulateData())

아래 그림과 같이 지정된 함수 내의 각 개별 코드 줄의 메모리 사용량 분석이 제공되었습니다.

“메모리 사용량” 열은 특정 코드 줄과 관련된 메모리 사용량을 나타내며, “증분” 열은 각 줄에 할당된 증분 메모리 오버헤드를 표시합니다. 또한 “발생 횟수” 열은 특정 코드 줄이 메모리를 할당하거나 할당 해제하는 빈도를 나타냅니다.

앞서 언급한 정보에 따르면, 11번 라인이 두 번 발생하여 메모리 사용량이 0.1MiB 증가하여 전체 메모리 사용량이 55.4MiB로 증가했습니다. 또한 19번과 22번 라인이 각각 0.2MiB와 0.3MiB를 추가하여 메모리 사용량이 55.9MiB로 소폭 상승했습니다.

이 글도 확인해 보세요:  JES를 활용한 흥미로운 사운드 처리 기법 3가지

타임스탬프로 파이썬 스크립트의 메모리 프로파일 찾기

터미널 내에서 mprof 명령을 실행하여 메모리\_프로파일러를 사용하여 파이썬 스크립트의 총 메모리 사용량을 유추할 수 있습니다.

 mprof run script_name.py

앞서 설명한 지시어는 0.1초 간격으로 지정된 스크립트의 주기적인 스니펫을 가져와서 수동 개입 없이 현재 작업 영역 디렉터리 내에 a.dat 파일을 생성합니다.

첨부된 데이터는 파이썬 프로그램에 의한 메모리 사용률의 시간적 분포를 나타내며, 프로파일러가 기록한 타임스탬프가 각 경우의 최종 값으로 추가되었습니다.

메모리 사용률 프로파일의 그래픽 표현은 matplotlib를 설치하여 사용하면 얻을 수 있습니다.

 pip install matplotlib

설치 후 다음과 같은 방법으로 mprof 명령을 실행합니다:

 mprof plot

수정된 텍스트에는 연구 결과가 보고되지 않았다고 명시되어 있습니다. 이는 다른 연구자들이 연구 결과를 바탕으로 해당 분야의 지식을 발전시키는 데 방해가 되므로 문제가 됩니다.

전용 파이썬 파일에서 스크립트 메모리 프로파일 실행

파이썬의 서브프로세스 기능 구현을 통해 특수 파이썬 모듈을 활용하여 다양한 파이썬 스크립트에 대한 프로파일을 생성할 수 있습니다.

이 접근 방식을 활용하면 메모리 프로파일러를 코드베이스의 나머지 부분과 분리하는 동시에 프로파일의 그래픽 표현을 로컬라이즈된 방식으로 저장할 수 있습니다.

 import subprocess

subprocess.run([
    'mprof', 'run', '--include-children', 'missing.py'
])

# save the plot output locally
subprocess.run(['mprof', 'plot', '--output=output.jpg'])

스크립트의 메모리 프로파일링을 실행하기 위해서는 앞서 언급한 코드가 포함된 Python 파일을 실행하기만 하면 됩니다. 이 작업을 수행하면 선택한 파일 위치의 디렉터리 내에 메모리 프로파일 플롯(output.jpg)의 그래픽 표현이 생성됩니다.

함수 실행에서 사용된 메모리 양 찾기

psutil 라이브러리를 사용하여 프로시저 또는 함수가 실행되는 동안의 포괄적인 메모리 할당 통계를 검색할 수 있습니다.

앞서 설명한 Pandas 데이터프레임 조작 방법을 다른 파이썬 스크립트에서 활용하기 위해 특정 스크립트의 코드 내에 통합할 수 있습니다.

 import psutil
import sys
import os
sys.path.append(sys.path[0] + "/..")

# import the class containing your method
from somecode.missing import Manipulate

# instantiate the class
manip = Manipulate()

process = psutil.Process(os.getpid())
initial_memory = process.memory_info().rss

# run the target method:
manip.manipulateData()

# get the memory information after execution
final_memory = process.memory_info().rss
memory_consumed = final_memory - initial_memory
memory_consumed_mb = memory_consumed / (1024 * 1024)
print(f"Memory consumed by the function: {memory_consumed_mb:.2f} MB")

아래 그림과 같이 메서드의 전체 메모리 사용량을 메가바이트(MB)로 표시하기 위해 분석이 수행되었습니다:

이 글도 확인해 보세요:  파이썬을 사용하여 FLAMES 게임 플레이하기

Jupyter Notebook에서 코드 줄의 메모리 프로파일 찾기

iPython과 함께 Jupyter Notebook을 활용하면 memory\_profiler를 사용하여 한 줄의 메모리 프로파일을 계산할 수 있습니다. 이 프로세스는 단일 셀에 memory\_profiler를 로드한 다음 후속 셀에 %memit 매직 함수를 추가하여 코드의 최대 메모리 소비량과 누적 크기에 대한 정보를 제공하는 과정을 포함합니다.

이 접근 방식은 Jupyter Notebook의 대화형 커널 내에서만 사용할 수 있는 특정 기능에 의존하므로 Jupyter Notebook 환경 외부에서 실행되는 표준 Python 스크립트에는 적합하지 않을 수 있다는 점에 유의하세요.

“예시”라는 단어는 측정 단위 또는 더 큰 그룹의 인스턴스 역할을 하는 것으로 정의할 수 있습니다. 커뮤니케이션에서 명확성과 맥락을 제공하는 데 자주 사용되며, 복잡한 개념을 더 작고 관리하기 쉬운 부분으로 나누어 개인이 더 쉽게 이해할 수 있도록 합니다.

주피터 노트북의 `%memit` 마법 함수를 사용하면 실행 중 함수의 메모리 사용량을 프로파일링할 수 있습니다.

파이썬 코드의 메모리 효율성 향상

파이썬 프로그래밍 언어는 고난도 데이터 조작 작업을 처리하는 데 자주 사용되므로 메모리 사용량을 효율적으로 관리하기 위해 모든 개별 코드 라인을 최적화하는 것이 필수적입니다. 파이썬에는 수많은 내장 함수가 있지만, 사용하지 않는 객체가 많으면 메모리 누수로 이어질 수 있습니다.

자신의 과거 행동을 되돌아보고 그 영향을 평가하는 것은 신중한 행동입니다

By 박준영

업계에서 7년간 경력을 쌓은 숙련된 iOS 개발자인 박준영님은 원활하고 매끄러운 사용자 경험을 만드는 데 전념하고 있습니다. 애플(Apple) 생태계에 능숙한 준영님은 획기적인 솔루션을 통해 지속적으로 기술 혁신의 한계를 뛰어넘고 있습니다. 소프트웨어 엔지니어링에 대한 탄탄한 지식과 세심한 접근 방식은 독자에게 실용적이면서도 세련된 콘텐츠를 제공하는 데 기여합니다.