Более быстрое решение для случайного текста W / R в Python

Мне нужно быстрое решение для случайных w/r текстовых фрагментов в Python. Что я хочу сделать, это так:

  1. Напишите фрагмент и запишите указатель
  2. Используйте указатель, чтобы получить фрагмент

Фрагменты имеют произвольную длину, и я предпочитаю не использовать базу данных для их хранения, а только указатели. Просто заменив методы файла Python на функции C (решение 1), это было довольно быстро, и указатели состоят только из "где" и "как долго" фрагмента. После этого я экспериментировал с тем, что мне показалось реальным, что работает с Berkeley DB. Я не знаю, как это назвать, что-то "пейджинговое"?

Дело в том, что этот код определенно работает, в 1,5-2 раза быстрее, чем решение 1, но он не намного быстрее и требует использования указателя из 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)

1 ответ

Решение

Это похоже на жесткий и непереносимый способ оптимизировать одну вещь - выделение памяти, выполняемое оболочками Python. file.read а также os.read, Все остальные части легко выполняются с помощью уже существующих функций в стандартной библиотеке Python. Есть даже простой способ выделить буфер чтения / записи в bytearray, io Модуль содержит метод readinto, который присутствует в типах файлов; Я очень подозреваю, что это помогает избежать распределения. Однако в самых популярных операционных системах мы можем пойти еще дальше - используя дисковый буфер ОС напрямую, а не выделять локальную память для нашего процесса. Это сделано с помощью mmap (но это становится сложно использовать, когда файл слишком велик для вашего адресного пространства). Для нераспределенного метода для чтения данных из файла mmaped просто используйте buffer(mm, offset, size),

Другие вопросы по тегам