Python 은 대형 배열 을 어떻게 보 내 고 받 습 니까?
네트워크 연결 을 통 해 연속 데 이 터 를 보 내 고 받 아들 이 는 대형 배열 을 통 해 데이터 복사 작업 을 최소 화해 야 합 니 다.
해결 방안
다음 함 수 는 memory views 를 이용 하여 큰 배열 을 보 내 고 받 습 니 다.
# zerocopy.py
def send_from(arr, dest):
view = memoryview(arr).cast('B')
while len(view):
nsent = dest.send(view)
view = view[nsent:]
def recv_into(arr, source):
view = memoryview(arr).cast('B')
while len(view):
nrecv = source.recv_into(view)
view = view[nrecv:]
테스트 프로그램 을 위해 우선 socket 으로 연 결 된 서버 와 클 라 이언 트 프로그램 을 만 듭 니 다.
>>> from socket import *
>>> s = socket(AF_INET, SOCK_STREAM)
>>> s.bind(('', 25000))
>>> s.listen(1)
>>> c,a = s.accept()
>>>
클 라 이언 트(다른 해석 기 에서):
>>> from socket import *
>>> c = socket(AF_INET, SOCK_STREAM)
>>> c.connect(('localhost', 25000))
>>>
이 절의 목 표 는 연결 을 통 해 초대형 배열 을 전송 하 는 것 이다.이 경우 array 모듈 이나 numpy 모듈 을 통 해 배열 을 만 들 수 있 습 니 다.
# Server
>>> import numpy
>>> a = numpy.arange(0.0, 50000000.0)
>>> send_from(a, c)
>>>
# Client
>>> import numpy
>>> a = numpy.zeros(shape=50000000, dtype=float)
>>> a[0:10]
array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
>>> recv_into(a, c)
>>> a[0:10]
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
>>>
토론 하 다.데이터 집약 형 분포 식 계산 과 평행 계산 프로그램 에서 스스로 프로그램 을 써 서 대량의 데 이 터 를 보 내 거나 받 아들 이 는 것 은 흔 하지 않다.그러나 만약 당신 이 확실히 이렇게 하고 싶다 면,낮은 층 의 네트워크 함수 에 사용 할 수 있 도록 데 이 터 를 원본 바이트 로 변환 해 야 할 수도 있 습 니 다.대부분의 네트워크 와 관련 된 함수 가 초대형 데이터 블록 을 한꺼번에 보 내 거나 받 아들 일 수 없 기 때문에 데 이 터 를 여러 블록 으로 절단 해 야 할 수도 있 습 니 다.
하나의 방법 은 특정한 메커니즘 을 사용 하여 데 이 터 를 직렬 화 하 는 것 이다.이 를 바이트 문자열 로 변환 할 수 있다.그러나 이렇게 하면 결국 데이터 의 복 사 를 만 들 수 있다.비록 당신 이 단편 적 으로 이런 일 을 하 더 라 도,당신 의 코드 는 결국 대량의 소형 복사 작업 을 할 것 입 니 다.
이 절 은 메모리 보 기 를 통 해 마법 동작 을 보 여 줍 니 다.본질 적 으로 하나의 메모리 보 기 는 이미 존재 하 는 배열 의 커버 층 이다.뿐만 아니 라 메모리 보 기 는 서로 다른 방식 으로 데 이 터 를 표현 할 수 있 습 니 다.이것 이 바로 아래 문장의 목적 이다.
view = memoryview(arr).cast('B')
이것 은 배열 arr 를 받 아들 여 기호 가 없 는 바이트 의 메모리 보기 로 변환 합 니 다.이 보 기 는 socket 관련 함수,예 를 들 어socket.send()
또는send.recv_into()
에 전 달 될 수 있 습 니 다.내부 에서 이 방법 들 은 이 메모리 영역 을 직접 조작 할 수 있다.예 를 들 어sock.send()
메모리 에서 데 이 터 를 복사 하지 않 고 직접 발생 합 니 다.send.recv_into()
이 메모리 영역 을 작업 을 받 는 입력 버퍼 로 사용 합 니 다.나머지 어 려 운 점 은 socket 함수 가 일부 데이터 만 조작 할 수 있다 는 것 이다.일반적으로 우 리 는 여러 가지 다른
send()
과recv_into()
을 사용 하여 전체 배열 을 전송 해 야 한다.걱정 하지 마 세 요.작업 할 때마다 보 기 는 바이트 수 를 보 내 거나 받 아들 여 새로운 보기 로 잘 립 니 다.새로운 보기 도 메모리 덮어 쓰기 층 입 니 다.그래서 복사 작업 은 전혀 없다.문 제 는 수신 자가 얼마나 많은 데 이 터 를 보 내야 하 는 지 미리 알 아야 한 다 는 것 이다.한 배열 을 미리 할당 하거나 받 아들 일 수 있 는 데 이 터 를 이미 존재 하 는 배열 에 넣 을 수 있 도록 해 야 한 다 는 것 이다.알 수 없다 면 발송 자 는 데이터 크기 를 먼저 보 낸 다음 실제 배열 데 이 터 를 보 내야 한다.
이상 은 Python 이 대형 배열 을 어떻게 보 내 고 받 는 지 에 대한 상세 한 내용 입 니 다.Python 이 대형 배열 을 받 는 자 료 를 보 내 는 것 에 대해 서 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Python의 None과 NULL의 차이점 상세 정보그래서 대상 = 속성 + 방법 (사실 방법도 하나의 속성, 데이터 속성과 구별되는 호출 가능한 속성 같은 속성과 방법을 가진 대상을 클래스, 즉 Classl로 분류할 수 있다.클래스는 하나의 청사진과 같아서 하나의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.