Использование mmap с popen - PullRequest
       22

Использование mmap с popen

2 голосов
/ 28 июня 2011

Мне нужно прочитать и обработать кучу ~ 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 ]

4 голосов
/ 28 июня 2011

со страницы руководства mmap(2):

   ENODEV The  underlying  file system of the specified file does not sup-
          port memory mapping.

Вы не можете создавать потоки mmap, только реальные файлы или анонимное пространство подкачки. Вам нужно будет самостоятельно читать из потока в память.

1 голос
/ 28 июня 2011

Трубы не являются отображаемыми.

case MAP_PRIVATE:
      ...
if (!file->f_op || !file->f_op->mmap)
        return -ENODEV;

и файловые операции канала не содержат mmap hook.

...