1

Python でのテキスト スニペットのランダム w/r に対する高速なソリューションが必要です。私がやりたいことは次のようなものです:

  1. スニペットを書き、ポインターを記録する
  2. ポインタを使用してスニペットを取得します

スニペットは任意の長さであり、データベースを使用してそれらを保存するのではなく、ポインターのみを使用することにしました。Python ファイル メソッドを C 関数に置き換えるだけで (解決策 1)、かなり高速になり、ポインターはスニペットの「場所」と「長さ」のみで構成されます。その後、Berkeley DB で動作する本物と思われるものを実験しました。何と呼べばいいのかわかりませんが、おそらく「ページング」のようなものでしょうか?

問題は、このコードはソリューション 1 よりも 1.5​​ 倍から 2 倍高速に動作することです。ただし、それほど高速ではなく、4 つの部分からなるポインターを使用する必要があります。おそらくこれは価値のある方法ではありませんが、大幅に改善する余地はありますか?

コードは次のとおりです。

from collections import namedtuple
from ctypes import cdll,c_char_p,\
     c_void_p,c_size_t,c_long,\
     c_int,create_string_buffer
libc = cdll.msvcrt
fopen = libc.fopen
fread = libc.fread
fwrite = libc.fwrite
fseek = libc.fseek
ftell = libc.ftell
fflush = libc.fflush
fclose = libc.fclose

#######################################################
# The following is how to write a snippet into the SnippetBase file

ptr = namedtuple('pointer','blk1, start, nblk, length')
snippet = '''
blk1: the first blk where the snippet is
start: the start of this snippet
nblk: number of blocks this snippet takes
length: length of this snippet
'''
bsize = 4096 # bsize: block size

fh = fopen('.\\SnippetBase.txt','wb')
fseek(fh,0,2)
pos1 = divmod(ftell(fh),bsize)
fwrite(snippet,c_size_t(len(snippet)),1,fh)
fflush(fh)
pos2 = divmod(ftell(fh),bsize)
ptr = ptr(pos1[0],pos1[1],pos2[0]-pos1[0]+1,len(snippet))
fclose(fh)


#######################################################
# The following is how to read the snippet from the SnippetBase file

fh = fopen('.\\SnippetBase.txt','rb')
fseek(fh,c_long(ptr.blk1*bsize),1)
buff = create_string_buffer(ptr.nblk*bsize)
fread(buff,c_size_t(ptr.nblk*bsize),1,fh)
print buffer(buff,ptr.start,ptr.length)
fclose(fh)
4

1 に答える 1