Найти - Пользователи
Полная версия: Как раскрыть потенциал современных NVMe SSD при сохранении/загрузке коллекций обьектов?
Начало » Python для экспертов » Как раскрыть потенциал современных NVMe SSD при сохранении/загрузке коллекций обьектов?
1 2
NVMeMaster
Дано: быстрый 1Tb NVMe SSD от Samsung

Нужно: выжать максимальную скорость при загрузке кеша (больших коллекций обьектов - классы со slots)
На старте пайтон программы, загружаются самописные индексы, по ним производится поиск, отдается результат.
Сами коллекции можно как угодно переписать, в том числе в виде библиотеки на Rust (но хотелось бы сначала выжать максимум из пайтона)

Посоветуйте что можно попробовать?
Есть также рамдиск для тестов

doza_and
NVMeMaster
Посоветуйте что можно попробовать?
На мой взгляд вам прежде всего надо поменять подход, постановку задачи.
NVMeMaster
Нужно: выжать максимальную скорость при загрузке кеша
При такой постановке путь к цели бесконечный, всегда можно еще что-то придумать.

Вам надо определиться какой скорости вам достаточно.

SSD обычно имеют несколько каналов. Можно попробовать грузить объекты в несколько потоков (2-4).
Скорость загрузки пиклов достаточно высокая, врядли вы существенно выиграете от переписывания на компилируемые языки.
NVMeMaster
Я думаю нужно читать и писать кеш в том же самом формате в каком он находится в оперативной памяти.
А чтобы эффективнее упаковать данные нужно использовать С или Rust массивы.
Как можно написать класс-обертку для превращения С-массива в рид-онли питон список?
Rodegast
> На старте пайтон программы, загружаются самописные индексы, по ним производится поиск, отдается результат.

Ничего не понятно. Какие индексы? Где они хранятся? Как хранятся данные на диске? В каком формате? Каким образом питоновские объекты записываются на диск?
NVMeMaster
В данный момент оно реализовано на простом pickle

Мне нужен быстрый поиск по ~8Gb текстовых файлов, логика поиска примерно такая же как в нотпад++
Только у меня индексы строятся заранее, а не в момент поиска.
Содержимое файлов загружается лениво (предпросмотр сделан на pyqt5 точно как на скриншоте. но графический режим и предпросмотр используется не всегда)


Если попытаться перевести скриншот в сишную структуру получится следующее:
struct SearchResult {
int file_path_hash; //file_path_hash == Python hash(file_path)
int str_start_index;
int line_number; //добавлено для предпросмотра в стиле нотпад++
int line_str_start_index; //для предпросмотра в стиле нотпад++
}

find_string будет именем файла, ну а содержимое файла - массив структур

Как видно я совсем отказался от хранения строки с file_path.
Вместо имени файла храню хеш пути к файлу и использую словарь int file_path_hash -> file_path в отдельном файле. (эту логику не нужно переписывать с Python на си)

Сейчас нужно компактно упаковать struct SearchResult в памяти.
А поскольку я выбросил все строки можно попробовать хранить это все в ПЛОСКОМ numpy.array
Вот так оно сериализуется в файл:

 arr = np.array([
    2147483647, ord('a'), ord('b'), ord('c'),
    2147483647 - 1, ord('q'), ord('w'), ord('e'),
    2147483647 - 2, ord('a'), ord('s'), ord('d'),
    2147483647 - 3, ord('z'), ord('x'), 2147483647
])
file_name = 'np_array.dat'
np.save(open(file_name, 'wb'), arr)
FishHook
Мне нужен быстрый поиск по ~8Gb текстовых файлов
ну вряд ли же вы первый кому понадобился “быстрый поиск по ~8Gb текстовых файлов”
что, совсем нет готового решения?
NVMeMaster
Вокруг моего решения уже выстроено много кастомной логики, отказаться от нее не выйдет.

Если делать np.save() / np.load() в разных потоках это решит все проблемы.
В идеале - на каждый файл индекса - свой поток, но не более некоторого максимального числа потоков.

В следующей итерации индексер файлов можно написать на Rust, просто имитируя формат файлов с np.array
Как думаете стоит ли заморачиваться с numpy, или же сразу написать библиотеку-обертку над сишной или Rust структурой и массивами
doza_and
NVMeMaster
Как думаете стоит ли заморачиваться с numpy, или же сразу написать библиотеку-обертку над сишной или Rust структурой и массивами

Лично у меня сложилось мнение что у вас сплошная каша в голове.

Начали вы с того что
NVMeMaster
Нужно: выжать максимальную скорость
Потом оказывается что
NVMeMaster
Сейчас нужно компактно упаковать struct SearchResult в памяти.

Вы не приводите никаких требований ни по быстродействию ни по объему памяти, вообще никаких. Непонятно что у вас за индекс (это словари или еще чтото). Непонятно на каком железе вы это будете запускать (объем памяти объем диска, сколько ядер тактовая частота). 8 гиг на современных машинах целиком в память влезут.

NVMeMaster
Вокруг моего решения уже выстроено много кастомной логики, отказаться от нее не выйдет.
Для меня это означает что архитектура приложения никуда не годится. Я бы такое выкинул и написал заново.

Я бы вам посоветовал для начала сравнить ваш индекс с существующими. Например с потнотекстовым поиском mongodb и с elastic search.

Я могу понять ваш подход если цель просто научиться языку и технологиям поиска. Но для продакшена обычно используют готовые, проверенные решения.
py.user.next
NVMeMaster
Мне нужен быстрый поиск по ~8Gb текстовых файлов, логика поиска примерно такая же как в нотпад++
Так это алгоритмически делается, скорее всего. В общем, опиши подробнее, какие файлы, что в них ищется. И опиши, что есть на данном этапе, как оно ищет (по какому алгоритму) и с какой скоростью.

NVMeMaster
Сами коллекции можно как угодно переписать, в том числе в виде библиотеки на Rust
Если у тебя тупой алгоритм, Rust тебе не поможет, потому что алгоритм так и останется тупым и, соотвественно, медленным.
NVMeMaster
doza_and
Вы не приводите никаких требований ни по быстродействию ни по объему памяти, вообще никаких.
Уточняю:
Нужно читать с диска blob в том же самом формате в каком он находится в оперативной памяти в Rust, а для Python допустим небольшой оверхед для переупаковки в родные коллекции, строки и прочие обертки над примитивами.

Переносимость win/linux, little/big-endian НЕ НУЖНА. Все будет запускаться на одной и той же машине с 64Gb RAM, память желательно использовать эффективно, но не в ущерб скорости сериализации/десериализации на такой ссд:

Памяти много, а потому БД мне не нужны. Нужны blob-файлы.

Я люблю писать консольные программы в Unix-way стиле.
99% моих наработок написаны на Python и одномоментно все переписать на Rust не представляется возможным (да и не нужно).
В последнее время изучаю Rust потому что он многопоточный и безопасный, а у меня сейчас есть 6 ядер/12 потоков.

Если Python и Rust смогут пользоваться условным общим форматом файлов для данных и кешей то я смогу писать консольные программы на Rust и пользоваться linux piping.
А графические оболочки к ним продолжу писать на Python и pyqt5 или pygtk3
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB