Этот вопрос задавали много раз. Потратив некоторое время на чтение ответов, я провел небольшое профилирование, чтобы опробовать различные методы, упомянутые ранее ...
- У меня есть файл 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 с, использование памяти ~ нет данных
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 с, использование памяти ~ нет данных
6) sqlite (with primary index on url):
время загрузки ~ 0 с, время поиска ~ 0,0 с, использование памяти ~ нет данных
Для моего вариант использования, похоже, что использование набора - лучший вариант, если у меня достаточно памяти. Я надеялся получить несколько комментариев по этим вопросам:
- лучшая альтернатива например, sqlite?
- Способы улучшить время поиска с помощью mmap . У меня 64-битная установка. [редактировать] например фильтры bloom
- По мере того, как размер файла увеличивается до пары ГБ, могу ли я как-то продолжать использовать "set", например разделить на части ..
[править 1] P.S. Мне нужно часто искать, добавлять / удалять значения, и я не могу использовать только хеш-таблицу, потому что мне нужно будет получить измененные значения позже.
Любые комментарии / предложения приветствуются!
[править 2] Обновление с результатами методов, предложенных в ответах [править 3] Обновление с результатами sqlite
Решение : на основе всех профилей и отзывов, я думаю, что выберу sqlite. Второй альтернативой является метод 4. Одним из недостатков sqlite является то, что размер базы данных более чем в два раза превышает размер исходного файла CSV с URL-адресами. Это происходит из-за первичного индекса на url