2009-06-17 4 views
2

지금은 문자열, StringIO 또는 cStringIO를 사용하여 바이트를 버퍼링하고 있습니다. 하지만 버퍼의 왼쪽에서 바이트를 제거해야하는 경우가 자주 있습니다. 순진적인 접근 방식은 전체 버퍼를 다시 작성합니다. 왼쪽 잘림이 매우 일반적인 작업 인 경우이를 수행하는 최적의 방법이 있습니까? 파이썬의 가비지 컬렉터는 실제로 잘라 버린 바이트를 GC해야합니다.왼쪽에서자를 수있는 파이썬 버퍼?

어떤 종류의 알고리즘 (작은 조각으로 버퍼를 유지 하시겠습니까?) 또는 기존 구현이 실제로 도움이됩니다.

편집 :

나는이 파이썬 2.7의 memoryview을 사용하려고하지만, 슬프게도, "보기"외부 데이터 원본 참조가 삭제 될 때 GCed되지 않습니다 :

# (This will use ~2GB of memory, not 50MB) 

memoryview # Requires Python 2.7+ 

smalls = [] 

for i in xrange(10): 
    big = memoryview('z'*(200*1000*1000)) 
    small = big[195*1000*1000:] 
    del big 
    smalls.append(small) 
    print '.', 
+0

왜 바이트를 제거 하시겠습니까? 완료 할 때 버퍼를 사용하지 않고 전체 버퍼를 버리는 것은 어떨까요? –

+0

(임의의 구분 기호로 구분 된) 전체 행이 버퍼에서 점진적으로 추출되어 콜백으로 전송됩니다. 버퍼를 주변에두면 메모리가 소모 될 수 있습니다. – ivank

+0

"메모리를 소모 할 수 있습니까?" 정말? 이 증거가 있습니까? 실제로 메모리를 소진했다는 증거가있을 때까지 이와 같은 것을 과도하게 최적화하는 것이 거의 도움이되지 않습니다. –

답변

3

deque는 효율적인 것 목록, 문자열 또는 버퍼, 양끝 제거를 위해 O (1)을 상각합니다). 그러나 문자열보다는 메모리를 사용하는 것이 비용이 많이들 것입니다. 패킹 된 시퀀스가 ​​아닌 각 문자열을 자체 문자열 개체로 저장하기 때문입니다.

또는 고정 된 크기의 문자열/버퍼 객체의 링크 된 목록과 같은 사용자 고유의 구현을 만들어 데이터를 더 압축 적으로 저장할 수 있습니다.

+0

deque에 대한 최근 링크 : http://docs.python.org/library/collections.html#deque-objects. –

+0

감사합니다. 링크를 업데이트했습니다. 방금 첫 번째 Google 결과를 사용하여 2.5.2 문서임을 알지 못했습니다. – Brian

1

버퍼를 문자 또는 줄의 목록으로 작성하고 목록을 분할하십시오. 출력시 문자열로만 결합하십시오. 이것은 대부분의 유형의 '변경 가능한 문자열'동작에 매우 효율적입니다.

GC는 더 이상 목록에서 참조되지 않기 때문에 잘린 바이트를 수집합니다.

업데이트 : 목록 머리를 수정하려면 간단히 목록을 뒤집을 수 있습니다. 이것은 비효율적 인 일이지만, python의리스트 구현은 내부적으로 이것을 최적화합니다. http://effbot.org/zone/python-list.htm에서

:

반전은 빠르고, 그래서 당신이 목록의 시작 부분에 제거하고 항목의 무리를 삽입해야하는 경우 목록을 반전 일시적으로 종종 일 최대 속도를 높일 수 :

왼쪽 제거 동작이 사용을 달리 (빈번한 경우
L.reverse() 
# append/insert/pop/delete at far end 
L.reverse() 
+0

여기 효율성이 염려되는 경우 배열 모듈의 배열을 대신 사용할 수 있습니다. – bayer

+0

목록에는 왼쪽 삭제에 대한 버퍼와 동일한 문제가 있지만 (메모리 할당 제외) 모든 바이트를 복사하여 제거로 생성 된 구멍을 채워야합니다. – Brian

+0

바이트를 복사하지 않고 참조를 복사합니다. 줄 단위로 추가 및 제거하는 경우 오버 헤드가 최소화됩니다. 목록을 뒤집을 수 없다면 (위의 대답 참조) – SpliFF

관련 문제