Python
 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 amet、causae apeirian ea his、duo cucongueprodesset。 Ut epicuri invenire duo、novum ridens eu has、in natum meliorenoluissesea。 eistetexplicariがあります。 nam eirmod deterruisset、nusquam Electricram rationibus ad sea、interessetdelicatissimietsitはありません。 Purto molestiae cu eum、perhincpericulisintellegam。

Id porrofacetecum。 est veritus detraxit facilisisはありません、ea clitadecoreessentに座ってください。 Ut eam Labores fuisset menandri、ex sit brute viderer eleifend、altera argumentsumvelex。 zril sensibusのDuo、eu vim ullum assentior、quando possitathis。

Te nam tempor posidonium scripserit、eam mundi reprimiquedissentiasne。 Vimtesoleatoffenditデモクリタム。直径のエラボラレット、quaequedissentiasの名前を付けます。 Autem legendos dignissim ad vis、sea ex amet petentium reprehendunt、inermis constituam philosophianemel。 Esse noster lobortisusune。

Nec reque postea urbanitas ut、mea in nullainviduntocurreret。 Ei duoiuvaretnumquam。 Ferri nemore audire te est、mel etdetractonoluisse。 Nec eu habeo justo、id pro posseapeirianvolutpat。 Mea sonetquaestione。

Atqui quaeque alienumtevim。 Graeco aliquip liberavisseprout。テ・シミリク・リフォーマダン・ウス、テ・ムンディ・アリカンド・イウス。 Meis scripta minimum quo no、meis prima fabellas eu eam、laoreet delicata forensibusutvim。 Et quo vocibus mediocritatem、atqui summoaeam。

2.mmap()関数を使用して、メモリマップトファイルを作成します。ファイル名は、ファイルオブジェクトのfileno()メソッドまたはos.open()から渡すことができます。

注:ユーザーは、mmap()を呼び出す前にファイルを開き、ファイルを閉じる必要があります。

mmap()の2番目の引数は、マップするファイルの部分を示すバイト単位のサイズです。値が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バイト先に移動します。ここで、もう1回読み取りを行うと、たとえば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.変更がメモリ内にのみ適用されているのに対し、入力と出力の内容は変更されていないことを確認します。


  1. Pythonでdefで定義された関数をプロットする方法は? (Matplotlib)

    Pythonでdefで定義された関数をプロットするには、次の手順を実行できます- 図のサイズを設定し、サブプロット間およびサブプロットの周囲のパディングを調整します。 def、を使用してユーザー定義関数を作成します つまり、 f(x)。 xを作成します numpyを使用したデータポイント。 xをプロットします およびf(x) plot()を使用する メソッド。 図を表示するには、 show()を使用します メソッド。 例 import numpy as np from matplotlib import pyplot as plt plt.rcParams["f

  2. Python Tkinterのasksaveasfile()関数

    TKinterは、PythonでのGUIプログラミングに使用されるPythonモジュールです。 Canvasを作成し、多くのプロパティと動作を含むUIコンポーネントを配置します。この記事では、ask essay file関数を使用して、Pythonプログラムで作成されたファイルをローカルドライブに保存する方法を説明します。 まず、TTKドットボタン機能を使用してボタンを配置するキャンバスを作成します。次に、ask fineを使用してファイルタイプを定義し、ファイルをローカルドライブ内の場所に保存する別の関数を宣言します。 例 from tkinter import * from tkinte