Этот вопрос задавался много раз. Проведя некоторое время, читая ответы, я сделал небольшое профилирование, чтобы опробовать различные методы, упомянутые ранее...
- У меня есть 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', например. расколоть его партиями.
[edit 1] P.S. Мне нужно часто искать, добавлять/удалять значения и не использовать одну хэш-таблицу, потому что мне нужно получить измененные значения позже.
Любые комментарии/предложения приветствуются!
[edit 2] Обновление с результатами методов, предложенных в ответах [edit 3] Обновление с помощью результатов sqlite
Решение. Основываясь на всех профилированиях и отзывах, я думаю, что пойду с sqlite. Второй альтернативный метод 4. Один недостаток sqlite заключается в том, что размер базы данных более чем в два раза превышает исходный файл csv с URL-адресами. Это связано с первичным индексом url