Computer >> 컴퓨터 >  >> 프로그램 작성 >> Python

MMAP 기능을 사용하여 Python에서 파일 읽기 성능을 향상시키는 방법은 무엇입니까?

<시간/>

소개..

파일에 매핑될 때 메모리 매핑으로 약칭되는 MMAP는 정상적인 I/O 기능으로 데이터에 액세스하는 대신 운영 체제 가상 메모리를 사용하여 파일 시스템의 데이터에 직접 액세스합니다. 각 액세스에 대해 별도의 시스템 호출을 수행하거나 버퍼 간에 데이터를 복사할 필요가 없으므로 I/O 성능이 향상됩니다.

사실 메모리에 생성된 SQLlite 데이터베이스와 같이 메모리에 있는 모든 항목은 디스크에 비해 성능이 더 좋습니다.

메모리 매핑된 파일은 수행하려는 작업에 따라 변경 가능한 문자열 또는 파일과 유사한 개체로 처리될 수 있습니다.

MMAP은 close(), flush(), read(), readline(), seek(), tell(), write()와 같은 많은 메소드를 지원하며 슬라이스 작업 및 정규 표현식과도 잘 작동합니다.

그것을 하는 방법..

1. 아래 내용의 텍스트 파일을 가정합니다. 이 텍스트는 Google을 사용하여 샘플 텍스트를 검색하여 얻을 수 있습니다. 이 내용을 input.txt 파일에 복사하십시오.

Lorem ipsum dolor sit met, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum riders eu has, in natum meliore noluisse sea. 설명이 있습니다. No nam eirmod deterruisset, nusquam electram rationibus ad sea, 관심사의 섬세함 등. Purto molestiae cu eum, in per hinc periculis intellegam.

Id porro facete cum. 아니 est veritus detraxit facilisis, sit ea clita decore essent. Ut eam laboures fuisset menandri, ex sit brute viderer eleifend, altera argumentum vel ex. Duo at zril sensibus, eu vim ullum assentior, quando possit at his.

Te nam tempor posidonium scripserit, eam mundi reprimique dissentias ne. Vim te soleat offendit democritum. Nam diam elaboraret, quaeque dissentias가 있습니다. Autem legendos dignissim ad vis, sea ex amet penentium reprehendunt, inermis constituam philosophia ne mel. Esse noster lobortis usu ne.

Nec reque postea urbanitas ut, mea in nulla invidunt occurret. Ei duo iuvaret numquam. Ferri nemore audire te est, mel et detracto noluisse. Nec eu habeo justo, id pro posse apeirian volutpat. Mea sonet quaestio ne.

Atqui quaeque alienum te vim. Graeco aliquip liberavisse pro ut. Te similique Reformidans usu, te mundi aliquando ius. Meis scripta minimum quo no, meis prima fabellas eu eam, laoreet delicata forensibus ut vim. Et quo vocibus mediocritatem, atqui summo eam.

2. mmap() 함수를 사용하여 메모리 매핑된 파일을 만듭니다. 파일 객체의 fileno() 메서드나 os.open()에서 파일 이름을 전달할 수 있습니다.

참고:사용자는 mmap()을 호출하기 전에 파일을 열고 닫을 책임이 있습니다.

mmap()에 대한 두 번째 인수는 매핑할 파일 부분을 나타내는 바이트 단위 크기입니다. 값이 0이면 전체 파일이 매핑됩니다. 읽기 전용 액세스의 경우 ACCESS_READ, 연속 쓰기 액세스의 경우 ACCESS_WRITE, 쓰기 액세스 시 복사의 경우 ACCESS_COPY인 추가 인수를 사용할 수도 있습니다.

import mmap

input_text = """Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.

Id porro facete cum. No est veritus detraxit facilisis, sit ea clita decore essent. Ut eam labores fuisset menandri, ex sit brute viderer eleifend, altera argumentum vel ex. Duo at zril sensibus, eu vim ullum assentior, quando possit at his.

Te nam tempor posidonium scripserit, eam mundi reprimique dissentias ne. Vim te soleat offendit democritum. Nam an diam elaboraret, quaeque dissentias an has. Autem legendos dignissim ad vis, sea ex amet petentium reprehendunt, inermis constituam philosophia ne mel. Esse noster lobortis usu ne.

Nec reque postea urbanitas ut, mea in nulla invidunt ocurreret. Ei duo iuvaret numquam. Ferri nemore audire te est, mel et detracto noluisse. Nec eu habeo justo, id pro posse apeirian volutpat. Mea sonet quaestio ne.

Atqui quaeque alienum te vim. Graeco aliquip liberavisse pro ut. Te similique reformidans usu, te mundi aliquando ius. Meis scripta minimum quo no, meis prima fabellas eu eam, laoreet delicata forensibus ut vim. Et quo vocibus mediocritatem, atqui summo an eam.

"""

# create a inout file with some text
input_file = 'input.txt'
f = open(input_file, "w+")
f.write(input_text)
f.close()

#Open the file in read mode
with open(input_file, 'r') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
print(f"Output \n*** Output first 5 bytes of the {input_file} is {m.read(5)} ")
print(f"*** Output Next 10 bytes of the {input_file} is {m.read(10)} ")
입니다.

출력

*** Output first 5 bytes of the input.txt is b'Lorem'
*** Output Next 10 bytes of the input.txt is b' ipsum dol'

3. 파일을 읽고 메모리에 매핑하고 .read()를 사용하여 처음 5바이트를 읽습니다. 따라서 파일 포인터는 처음 읽은 후 10바이트 앞으로 이동합니다. 이제 한 번 더 읽기를 수행하면 read(10) 바이트가 6 - 15바이트를 제공합니다.

4. 업데이트할 메모리 매핑 파일을 설정하려면 매핑하기 전에 'r+'('w' 아님)용으로 엽니다.

선의 일부를 제자리에서 수정하는 방법을 예시로 보여드리겠습니다.

import mmap
import shutil

input_file = 'input.txt'
input_copy = input_file.replace('input','input_copy')

# Make a Copy of the file just to make sure original is un-modified.
shutil.copyfile(input_file,input_copy)

# word
word = b'ipsum'

# modified word
modified_word = word[::-1]

# Open the file to receive updates
with open(input_copy, 'r+') as f:
with mmap.mmap(f.fileno(), 0) as m:
print(f"output \n *** Line before updates \n {m.readline().rstrip()}")

# Rewind using seek
m.seek(0)

# find the word and reverse it
loc = m.find(word)
m[loc:loc + len(word)] = modified_word
m.flush()

# Rewind using seek
m.seek(0)
print(f" \n *** Line after updates \n {m.readline().rstrip()}")

f.seek(0)
print(f" \n *** Final file \n {f.readline().rstrip()}")

출력

*** Line before updates
b'Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.'

*** Line after updates
b'Lorem muspi dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.'

*** Final file
Lorem muspi dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.

5.메모리와 파일의 첫 번째 줄 중간에 "ipsum"이라는 단어가 대체됩니다.

6. 어떤 이유로든 메모리 내 변경 사항을 확인하고 디스크의 파일을 업데이트하지 않으려면 ACCESS_COPY를 사용하십시오.

import mmap
import shutil

input_file = 'input.txt'
input_copy = input_file.replace('input','input_copy')

# Make a Copy of the file just to make sure original is un-modified.
shutil.copyfile(input_file,input_copy)

# word
word = b'ipsum'

# modified word
modified_word = word[::-1]

# Open the file to receive updates
with open(input_copy, 'r+') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_COPY) as m:
print(f"output \n *** Line before updates \n {m.readline().rstrip()}")

# Rewind using seek
m.seek(0)

# find the word and reverse it
loc = m.find(word)
m[loc:loc + len(word)] = modified_word
m.flush()

# Rewind using seek
m.seek(0)
print(f" \n *** Line after updates \n {m.readline().rstrip()}")

f.seek(0)
print(f" \n *** Final file \n {f.readline().rstrip()}")

출력

*** Line before updates
b'Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.'

*** Line after updates
b'Lorem muspi dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.'

*** Final file
Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.

7. 변경 사항이 메모리 내에만 적용되는 동안 변경되지 않은 입력 및 출력의 내용을 관찰합니다.