Ответ 1
Во-первых, память вашей машины не имеет значения. Это размер вашего процесса адресное пространство, которое имеет значение. С 32-разрядным Python это будет где-то менее 4 ГБ. С 64-битным Python его будет более чем достаточно.
Причина этого в том, что mmap
не о сопоставление файла в физической памяти, но в виртуальную память. Пешеходный файл mmap
становится таким же, как специальный файл подкачки для вашей программы. Размышление об этом может немного осложниться, но ссылки Wikipedia выше должны помочь.
Итак, первым ответом является "использование 64-битного Python". Но, очевидно, это может быть неприменимо в вашем случае.
Очевидной альтернативой является карта в первом 1 ГБ, поиск, который, отмените его, карту в следующем 1 ГБ и т.д. Как вы это делаете, указав параметры length
и offset
на mmap
метод. Например:
m = mmap.mmap(f.fileno(), length=1024*1024*1024, offset=1536*1024*1024)
Однако регулярное выражение, которое вы ищете, можно найти на полпути в первом 1 ГБ, а второе - во втором. Итак, вам нужно использовать оконную карту в первом 1 ГБ, искать, развязать, а затем отображать частично перекрывающиеся 1 ГБ и т.д.
Вопрос в том, сколько перекрытий вам нужно? Если вы знаете максимально возможный размер матча, вам не нужно ничего больше. И если вы не знаете... ну, тогда нет возможности реально решить проблему, не разбивая ваше регулярное выражение, если это не очевидно, представьте, как вы могли бы найти совпадение 2 ГБ в одном окне на 1 ГБ.
Отвечая на следующий вопрос:
Так как я устанавливаю буфер на 10 МБ, с точки зрения производительности, то он такой же, как у mmap 10 Мбайт файла?
Как и в случае с любым вопросом производительности, если это действительно имеет значение, вам нужно его протестировать, а если нет, не беспокойтесь об этом.
Если вы хотите, чтобы я догадался: я думаю, что mmap
может быть быстрее здесь, но только потому, что (как подразумевал JF Себастьян), цикл и вызов re.match
128K раз, как часто может привести к тому, что ваш код будет привязан к процессору вместо IO переплет. Но вы можете оптимизировать это без mmap
, просто используя read
. Таким образом, mmap
будет быстрее, чем read
? Учитывая размеры, я ожидал бы, что производительность mmap
будет намного быстрее на старых платформах Unix, примерно на современных Unix-платформах, и немного медленнее в Windows. (Вы можете получить большие преимущества производительности из mmap
более read
или read
+ lseek
, если используете madvise
, но это не имеет значения здесь.) Но на самом деле это просто предположение.
Наиболее убедительной причиной использования mmap
обычно является то, что он проще, чем read
-ограниченный код, а не быстрее. Когда вам нужно использовать windowing даже с mmap
, и когда вам не нужно искать с помощью read
, это менее убедительно, но все же, если вы попытаетесь написать код в обоих направлениях, я бы ожидал, что ваш mmap
код будет более читабельным. (Особенно, если вы попытались оптимизировать копии буфера из очевидного решения read
.)