6

大きなテキスト ファイル (~232GB) からいくつかのキーワードを検索しようとしています。速度を考慮してバッファリングを利用し、それらのキーワードを含む行の開始位置を記録したいと考えています。

ここで、同様の質問について議論している多くの投稿を見てきました。ただし、バッファリング (イテレータとしてファイルを使用) を使用するソリューションは、正しいファイル位置を与えることができず、これらのソリューションは通常f.readline()、バッファリングを使用しない を使用するだけで正しいファイル位置を与えることができます。

両方を実行できる唯一の答えは次のとおり です。

# Read in the file once and build a list of line offsets
line_offset = []
offset = 0
for line in file:
    line_offset.append(offset)
    offset += len(line)
file.seek(0)

# Now, to skip to line n (with the first line being line 0), just do
file.seek(line_offset[n])

ただし、offset += len(line)操作に無駄な時間がかかるかどうかはわかりません。これを行うより直接的な方法はありますか?

アップデート:

私はいくつかのタイミングを取りましたが、.readline()ファイルオブジェクトをイテレータとして使用するよりもはるかに遅いようですpython 2.7.3. 次のコードを使用しました

#!/usr/bin/python

from timeit import timeit

MAX_LINES = 10000000

# use file object as iterator
def read_iter(): 
    with open('tweets.txt','r') as f:
        lino = 0
        for line in f:
            lino+=1
            if lino == MAX_LINES:
                break

# use .readline()
def read_readline(): 
    with open('tweets.txt', 'r') as f:
        lino = 0
        for line in iter(f.readline,''):
            lino+=1
            if lino == MAX_LINES:
                break

# use offset+=len(line) to simulate f.tell() under binary mode
def read_iter_tell(): 
    offset = 0
    with open('tweets.txt','rb') as f:
        lino = 0
        for line in f:
            lino+=1
            offset+=len(line)
            if lino == MAX_LINES:
                break

# use f.tell() with .readline()
def read_readline_tell():
    with open('tweets.txt', 'rb') as f:
        lino = 0
        for line in iter(f.readline,''):
            lino+=1
            offset = f.tell()
            if lino == MAX_LINES:
                break

print ("iter: %f"%timeit("read_iter()",number=1,setup="from __main__ import read_iter"))
print ("readline: %f"%timeit("read_readline()",number=1,setup="from __main__ import read_readline"))
print ("iter_tell: %f"%timeit("read_iter_tell()",number=1,setup="from __main__ import read_iter_tell"))
print ("readline_tell: %f"%timeit("read_readline_tell()",number=1,setup="from __main__ import read_readline_tell"))

結果は次のようになります。

iter: 5.079951
readline: 37.333189
iter_tell: 5.775822
readline_tell: 38.629598
4

1 に答える 1