Использование mmap с popen
Мне нужно прочитать и обработать кучу ~40 МБ сжатых текстовых файлов, и мне нужно, чтобы это было сделано быстро и с минимальными затратами на ввод / вывод (поскольку тома также используются другими). Самый быстрый способ, который я нашел для этой задачи, выглядит следующим образом:
def gziplines(fname):
f = Popen(['zcat', fname], stdout=PIPE)
for line in f.stdout:
yield line
а потом:
for line in gziplines(filename)
dostuff(line)
но то, что я хотел бы сделать (если это быстрее?) примерно так:
def gzipmmap(fname):
f = Popen(['zcat', fname], stdout=PIPE)
m = mmap.mmap(f.stdout.fileno(), 0, access=mmap.ACCESS_READ)
return m
к сожалению, когда я пытаюсь это сделать, я получаю эту ошибку:
>>> m = mmap.mmap(f.stdout.fileno(), 0, access=mmap.ACCESS_READ)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
mmap.error: [Errno 19] No such device
хотя, когда я пытаюсь:
>>> f.stdout.fileno()
4
Итак, я думаю, что у меня есть базовое недопонимание того, что здесь происходит.:(
Два вопроса:
1) Будет ли этот mmap более быстрым способом помещения всего файла в память для обработки?
2) Как мне этого добиться?
Большое спасибо... все здесь были невероятно полезны уже! ~Nik
2 ответа
От mmap(2)
справочная страница:
ENODEV The underlying file system of the specified file does not sup- port memory mapping.
Вы не можете mmap потоки, только реальные файлы или анонимное пространство подкачки. Вам нужно будет читать из потока в память самостоятельно.
Трубы не являются mmapable.
case MAP_PRIVATE:
...
if (!file->f_op || !file->f_op->mmap)
return -ENODEV;
и файловые операции канала не содержат mmap
крюк.