Этот вопрос задавался много раз. Потратив некоторое время на чтение ответов, я провел небольшое профилирование, чтобы опробовать различные методы, упомянутые ранее ...
- У меня есть файл 600 МБ с 6 миллионами строками строк (пути категорий из проекта DMOZ).
- Запись в каждой строке уникальна.
- Я хочу загрузить файл один раз & продолжить поиск совпадений в данных
Три метода, которые я попробовал ниже, перечисляют время, необходимое для загрузки файла, время поиска для отрицательного совпадения и использование памяти в диспетчере задач
1) set :
(i) data = set(f.read().splitlines())
(ii) result = search_str in data
Время загрузки ~ 10 с, Время поиска ~ 0,0 с, Использование памяти ~ 1,2 ГБ
2) list :
(i) data = f.read().splitlines()
(ii) result = search_str in data
Время загрузки ~ 6 с, Время поиска ~ 0,36 с, Использование памяти ~ 1,2 ГБ
3) mmap :
(i) data = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
(ii) result = data.find(search_str)
Время загрузки ~ 0 с, Время поиска ~ 5,4 с, Использование памяти ~ NA
4) Hash lookup (using code from @alienhard below):
Время загрузки ~ 65 с, Время поиска ~ 0,0 с, Использование памяти ~ 250 МБ
5) File search (using code from @EOL below):
with open('input.txt') as f:
print search_str in f #search_str ends with the ('\n' or '\r\n') as in the file
Время загрузки ~ 0 с, Время поиска ~ 3,2 с, Использование памяти ~ NA
6) sqlite (with primary index on url):
Время загрузки ~ 0 с, Время поиска ~ 0,0 с, Использование памяти ~ NA
Для моего случая использования кажется, что использование набора - лучший вариант, если у меня достаточно доступной памяти. Я надеялся получить некоторые комментарии по этим вопросам:
- A лучшая альтернатива например sqlite?
- Способы улучшить время поиска с помощью mmap . У меня есть 64-битная установка.
[редактировать] например фильтры Блума
- Поскольку размер файла увеличивается до пары ГБ, есть ли способ, которым я могу продолжать использовать 'set', например разбить его на партии ..
[править 1] П.С. Мне нужно часто искать, добавлять / удалять значения и не могу использовать только хэш-таблицу, потому что мне нужно получить измененные значения позже.
Любые комментарии / предложения приветствуются!
[править 2] Обновление с результатами методов, предложенных в ответах
[править 3] Обновление с результатами sqlite
Решение : Основываясь на профилировании и обратной связи, я думаю, я пойду с sqlite. Второй альтернативой является метод 4. Недостатком sqlite является то, что размер базы данных более чем в два раза превышает исходный файл csv с URL-адресами. Это связано с первичным индексом на URL