프로그래밍 언어/Python

memoryview 성능 테스트 ( feat.timeit, 버퍼프로토콜 )

JMDev 2023. 9. 23. 13:40

timeit 라이브러리는 작은단위의 코드에 실행시간을 테스트할 수 있는 유용한 도구입니다.

이 도구를 사용하여 파이썬에서 제공해주는 단순한 바이트배열과 memoryview 라는 객체를 활용하였을 때

성능적으로 얼마나 큰 차이점이 발생하고 왜 이런 차이점이 발생하는지 알아보겠습니다

import os
import timeit

video_data = 100 * os.urandom(1024 * 1024)
byte_offset = 1234
size = 20 * 1024 * 1024

def run_test():
    chunk = video_data[byte_offset:byte_offset + size]

result = timeit.timeit(
    stmt='run_test()',
    globals=globals(),
    number=100) / 100

print(f'{result:0.9f} seconds')
# 0.001633870 seconds

video_view = memoryview(video_data)

def run_test2():
    chunk = video_view[byte_offset:byte_offset + size]

result = timeit.timeit(
    stmt='run_test2()',
    globals=globals(),
    number=100) / 100

print(f'{result:0.9f} seconds')
# 0.000000150 seconds

기존 바이트배열을 활용하면 1633870(소수점생략) 이 걸리던 것이 똑같은 데이터를 memoryview로 감싸서

실행한 결과, 150 밖에 걸리지 않습니다.

초로 환산하면 1.6초(대략), 0.00015초 차이가 납니다.

여기서 만일 바이트배열을 활용해 1분이 걸리는 작업이 있다고 가정한다면,

memoryview에서는 0.0xx 초 단위로 실행이 되니 실로 어마어마한 차이며,

만일 동영상데이터를 서비스하기 위해 1초동안 10MB 데이터들을 처리해야 한다면

0.001633870/1 * 10MB = 600MB (대략)

0.000000150/1 * 10MB ≈ 66,666MB/초 ≈ 65GB/초

를 처리할 수 있을 것이고 결과를 보고 속도차이에 대한 체감이 될 것 같습니다

 

그렇다면 도대체 memoryview는 어떤 녀석이길래 이런 미친성능을 보여주는 것일까요?

 

memoryview는 파이썬에서 제공하는 고성능 버퍼 프로토콜을 활용한 내장 타입입니다.

이를 사용하면 객체의 슬라이스에 대해 복사 없이 직접 읽고 쓸 수 있는 인터페이스를 얻을 수 있습니다.

이는 바이트 슬라이싱을 할 때 메모리를 복사하여 CPU 시간을 점유하는 방식에 비해 뛰어난 성능을 보여주고 있음을 위에서 알 수 있죠.

버퍼 프로토콜

버퍼 프로토콜은 객체가 아닌, 하부 데이터 버퍼에 접근할 수 있는 저수준의 C API입니다.

이를 통해 개발자는 객체의 메모리 레이아웃에 직접 접근할 수 있게 되어, 데이터 처리의 효율성이 크게 향상됩니다.

memoryview의 장점

memoryview의 주요 장점 중 하나는 슬라이싱을 할 때 새로운 memoryview 인스턴스를 생성한다는 것입니다.

이는 메모리 복사가 발생하지 않고, 대용량 데이터를 처리할 때 시간과 메모리 사용량을 크게 절약할 수 있습니다.

bytearray와의 조합

bytearraybytes와 유사하지만 변경 가능한 타입을 제공합니다.

memoryviewbytearray로 감싸면, 복사의 추가 비용 없이 수신받은 데이터를 버퍼에서 원하는 위치에 스플라이스할 수 있게 됩니다. 그래서 네트워크 통신이나 파일 입출력 등에서 데이터를 효율적으로 처리할 수 있게 해줍니다.

결론

memoryview는 파이썬의 버퍼 프로토콜을 활용하여, 데이터를 복사하지 않고도 직접 읽고 쓸 수 있는 인터페이스를 제공합니다.

이를 통해 개발자는 메모리 사용과 CPU 시간을 크게 절약할 수 있으며, 특히 대용량 데이터를 다룰 때 이러한 이점이 두드러집니다. bytearray와 결합하여 사용하면, 데이터의 효율적인 처리가 가능해져 고성능 애플리케이션 개발에 성능을 최적화하는데 꼭 필요한 기능이라고 생각됩니다

 

memoryview와 bytearray와의 차이점을 설명한 그림

memoryview와 bytearray 슬라이싱할 때 차이점