|
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
|
|||||||||||
.NET 7 Как быстро определять наличие строк в файле, при этом не засоряя ОЗУ?25.10.2023, 22:55. Показов 3910. Ответов 45
Метки нет (Все метки)
Есть код, который находится в цикле. Мне нужно при каждой генерации проверять, есть ли сгенерированная строка в файле. Если есть, записать в другой файл. Раньше делал так:
Кликните здесь для просмотра всего текста
Вот несколько строк из файла (все они одинаковой длины): Кликните здесь для просмотра всего текста
fd512f88908e949f7f07c99167799a075c274f1 ff0a33055ea4e6669a3925a94e0a28fb256be5d 99dc7be5c1c761f3f4a0249309a6786fa91d0fb 909fd0f1dcb3149e764212d8279a1d2bc687028 ec4c98b0745d3d7095b85c2d57bafd6befd8681 fb5252617abc7bf0adfc19b0aeb1d8adfb27fd4 8d6f71698b00693009d18c6ed6fae3733932078 17d855fc899e183f150ddf52269d3781f6bbbfb 618512eaf1f16364eecdf63e7de46d3e972e568 0ade12db0026cafb67a2717484e4bb02e40f2f3 c5017274e5bc5c3ca1c9ba7dc19fe8341aa9134 ce5d60fef69ed01a2245084dbeaee4a69ae4afa 7b62f067bd38af3735299df0ba68a11bec52966 ... Но такой метод не вариант, жрёт слишком много ОЗУ (получается ~1,7 Гб занятой ОЗУ из 391 Мб файла). А мне нужно будет использовать файл размером до 2,5Гб. Также пробовал использовать алгоритм - фильтр Блума из ГитХаба: Кликните здесь для просмотра всего текста
Но при использовании файла размером ~2Гб (более 50 млн строк) происходит слишком много ложный срабатываний. Что предложите делать? Хочется, чтобы результат был - "Да, такая строка точно есть в файле, записываем", а не как с фильтром Блума
0
|
|||||||||||
| 25.10.2023, 22:55 | |
|
Ответы с готовыми решениями:
45
Проверка на наличие двух одинаковых строк в файле Проверить наличие всех нужных строк в файле |
|
|
|
| 27.10.2023, 15:11 | |
|
0
|
|
|
14370 / 9471 / 1360
Регистрация: 21.01.2016
Сообщений: 35,741
|
|
| 27.10.2023, 15:16 | |
|
Andrey-MSK, проект на питоне...
0
|
|
|
|
|||||||
| 27.10.2023, 15:25 | |||||||
![]() Evil12Boy, Вот вам запрос для БД на вставку данных, которых нет в другой таблице. Можете запускать раз в 5 секунд, а строки генерить в таблицу MyTable01
1
|
|||||||
|
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
|
||
| 27.10.2023, 18:00 | ||
|
0
|
||
|
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
|
||
| 27.10.2023, 18:40 [ТС] | ||
|
0
|
||
|
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
|
|||||
| 27.10.2023, 19:40 [ТС] | |||||
|
Ну и я дал ссылку на хабр пару сообщений назад, сейчас пытаюсь именно это реализовать, но чувствую знаний не хватит( Добавлено через 14 минут Добавлено через 30 секунд
0
|
|||||
|
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
|
|
| 27.10.2023, 19:51 | |
|
0
|
|
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|
| 27.10.2023, 20:31 | |
|
В общем, под ваши условия у меня получилось 1-2ms при поиске на одном ядре по 60млн строк:
1. Исходный файл форматируется согласно моему первому сообщению. 2. Исходный файл разбивается на 62 файла, в каждом из которых хранятся строки, начинающиеся на одинаковый байт. 3. Первый байт из строк убирается и переносится в имя файла (экономим 60млн байт и в памяти, и на диске). 4. Файлы загружаются в словарь <byte, byte[]>, где ключ - первый байт "слова", значение - массив строк из соответствующего файла. 5. При поиске сначала по первому байту сгенерированного слова выбираем из словаря нужный массив и далее ищем сгенерированную строку только по нему (за исключением первого байта). Но в память это всё в любом случае загрузить придётся. Я в алгоритмах не особо силён, так что не знаю как называется подобный тип индекса. Но судя по тому, что получилось, можно точно так же разбить исходный буфер на ещё большее количество маленьких буферов, где ключом будут первые два байта слова. Получится 3844 буферов, накладные расходы памяти на указатели этих массивов (и на словарь) будут незначительными, но при этом скорость поиска возрастёт ещё на порядок (и в сумме -120МБ на диске и в памяти). Более того, т.к. файлы получатся всего по ~600 килобайт, то чисто теоретически, если положить их на SSD, можно попробовать их даже в памяти не держать, а подгружать по необходимости. Вероятно, скорость вполнее приемлемая будет, особенно учитывая, что сама ОС будет кэшировать эти файлы на какое-то время после очередного обращения (ну т.е. память оно всё равно сожрёт, но отображаться это будет не в процессе вашего приложения). Учитывая, что случайные строки у вас генерятся равномерно, то распределение их по файлам тоже получится равномерное. Оптимизацию самого кода не проводил. Вероятно, если заморочиться на прямую работу с памятью и кэширование части вычисляемых значений, то можно и в этом месте скорость увеличить.
2
|
|
|
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
|
||
| 27.10.2023, 21:43 | ||
|
0
|
||
|
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
|
|
| 27.10.2023, 21:49 | |
|
Someone007,
Тут ведь совершенно конкретный случай с конкретными цифрами. Вряд ли накладные расходы всего на 3844 массивов превысят те 120МБ, которые были сэкономлены на размере самих буферов. Да и один словарь тоже много памяти не займёт. Да, там внутри, насколько помню, при таком наборе ключей, будет выделена память под 3844 корзины (под каждый уникальный ключ), но опять же, не может всё это вместе аж 120МБ потребовать. Ну и если "индексировать" только по одному байту, то там всего 62 массива получается, а прирост скорости сразу более, чем в 100 раз, чем если каждый раз по всему изначальному буферу искать.
0
|
|
|
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
|
|
| 27.10.2023, 21:52 [ТС] | |
|
Я отметил ответ, хотя это и не подходит под мои цели (но человеку всё равно очень благодарен за попытку помочь
). Буду и дальше использовать либо фильтр Блума, либо поищу другие алогоритмы, либо банально через HashSet<string>. Отметил ответ потому, что уже полностью убедился в том, что не найду здесь нужного мне ответа. И виноват в этом исключительно я)
0
|
|
|
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
|
||
| 28.10.2023, 01:09 | ||
|
0
|
||
|
|
||||||||||||
| 28.10.2023, 04:35 | ||||||||||||
|
Не по теме: Хвост мудрейшей Хоро, чем я занимаюсь?! Нет, чтобы спокойно задротить в геншин... Итак, сейчас будет магия вне Хогвартса, так что за последствия не отвечаю. А если серьезно: 1. у нас словарь из 62 символов. Т.е. мы можем упаковать в 1 байт 4 таких символа 2. у нас вроде как одинаковая длина символов. На этом тоже можно "оптимизировать" проходы, когда конвертнем всё в тупо массив байт. В целом, если приспичит, вопрос решаемый с помощью нулевого разделителя (но просядет скорость). Сначала формирую файл для опытов. Как-то так (я так и не понял 39 символов или 38, остановлися на 38, но конкретно длина погоды не делает)
- метод, позволяющий перегнать string в byte[], который будет "упакованый в меньший размер" ( в примере ниже это класс NyaConvertor) - считывание из файла в ОЗУ в виде недоиндекса (как предложил kotelok) Это блок Dictionary<byte, byte[]> ReadAllFile()- поиск входной строки по этому самому кешу (строку предварительно тоже переганяем в сжатый формат)
- формирование кеша из 3Гб занимает ~1минуту (проверял в Release сборке) - кеш отьедает менее 3Гб ОЗУ. Тестировал на х86 -- вроде не падало - что 50, что 50к строк для поиска проглатывает моментально. Надо по хорошему замерить сколько именно ищет, без учета формирования кеша, но это уже без меня. - для 300Мб я бы выкинул упаковку кеша, просто считал как есть в ОЗУ или около того. - если с памятью вообще притык -- тут только скидывать на файлы. Можно заморочится, чтобы кеш был "умным" и подгружал по необходимости... без меня. В целом, если вам нужно один раз загрузить файл в память, а потом ооооочень много раз (эдак 1кк, не меньше) к нему обращаться -- вариант рабочий. P.S.
В целом код на 99% состоит из идей kotelok + упаковка. Была попытка замерить "сразу за один проход искать N-строк, а не одну", но почему-то такой подход ещё медленее, чем по одной строке. Ну либо профит начинается с 1к записей, а ждать 100500 часов желания нет.
по "фильтр Блума" из того же Хабра
- если мы НЕ НАШЛИ вхождение, значит его 100% нет - если мы НАШЛИ вхождение, то это не означает что элемент реально входит, а не тупо колизия. На 80+ лямах записи -- вообще никаких гарантий. По поводу "там есть программа, которая юзает 10Мб".... Ну, не знаю что там за колдунство, но вот простой вопрос -- как можно инфу на 3ГБ перегнать в 10Мб без потерь? Либо там таки работа с временными файлами, либо алгоритм делает что-то другое. Чудес как правило не бывает.
3
|
||||||||||||
|
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
|
||
| 28.10.2023, 13:21 [ТС] | ||
|
Wolfdp, очень благодарен! Буду пока-то использовать именно это (HashSet и фильтр Блума теперь нервно курят в стронке). А что вы можете сказать на счёт алгоритмов Boyer–Moore`а и Rabin–Karp`а ?
Добавлено через 47 секунд
0
|
||
|
|
||
| 28.10.2023, 14:10 | ||
|
На всякий -- перепроверте работоспособность кода, т.к. тестировал бегло. Также учтите что кеш считывался с М.2 SSD диска и системы где явно избыток ОЗУ. В реальности на WindowsXP (которая в целом видит только 3ГБ оперативки) и на HDD это будет выглядеть не столь бодро.
0
|
||
|
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
|
|
| 28.10.2023, 16:20 [ТС] | |
|
Код работает нормально (хотя запускал тоже на m.2 ssd), на более слабом железе протестирую позже. А сейчас я хочу испробовать два новых алгоритма, мне кажется алгоритм Карпа (при правельной реализации) именно то, что мне нужно)
0
|
|
|
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
|
||||||
| 29.10.2023, 00:39 [ТС] | ||||||
|
М-да . . . Отсортировал я файл (391 Мб) по алфавиту (кнопка F9 в Sublime Text и готово).
Дальше нашел реализацию бинарного поиска на питоне. Цитирую автора скрипта: Кликните здесь для просмотра всего текста
у меня поиск занимает около полторы тысячных секунды на файле 2ГБ с 46.6 миллионами случайных строк длиной 40-50 символов каждая. Вот код: Кликните здесь для просмотра всего текста
Скорость - предостаточная. ОЗУ не нагружает вообще. Остаётся написать подобное на C# и это то, что я искал)
0
|
||||||
|
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
|
|
| 29.10.2023, 16:33 [ТС] | |
|
Лично у меня не получилось переписать код из Python в C#
![]() Никогда не приходилось работать с MemoryMappedFiles
0
|
|
| 29.10.2023, 16:33 | |
|
Как при открытии этого файла сделать что бы он загружал мой редактор и с текстом находящейся в этом файле? Ввести данные слов в N строк в файл и сделать сортировку по алфавиту в этом файле Подсчет количества строк в текстовом файле, имя которого задано первым параметром КФ. Проверить наличие указа Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Теория всего 12. ВГК
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики
1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
|
Публикация отклонённая на хабре. Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование задачи и целеполагание
Hrethgir 21.07.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11948&stc=1&d=1784657928
Привет Хабр. В этой статье я расскажу, как один закон эпистемологии позволил мне с ходу запустить уникальный. . .
|
Теория всего 11. Основные параметры
anaschu 21.07.2026
Дешифровка тензорного ядра Soil Chemistry 2. 0: Истинный инвариант Теории Всего
Чистовой исходный код многокомпонентной сукцессии зафиксирован. Модель оперирует единым вектором состояния. . .
|
Теория всего 10. Клод трусишка
anaschu 21.07.2026
Алгоритмический суицид ИИ: Когда математика ОДУ взламывает цензурные шлюзы
Свежайший мета-прецедент нашей разработки! Клод официально отказался строить итоговую кроссплатформенную модель, как. . .
|
|
Теория всего 9. Окончательная проработка метафоры "дерево = традиции"
anaschu 21.07.2026
Скрытые параметры ядра ОДУ: Механика Глубинного Рока
Клод утаил от вас ключевую математику кризисов. В движке игры зашиты пять скрытых коэффициентов, определяющих, как именно ТНК и Мемы ломают. . .
|
Теория всего 8. Clauude трусишка. Ответ джемени
anaschu 21.07.2026
Игровой баланс «Модели Всего»: Алгоритмический блок как механика Семантического БуфераЭтот скриншот отказа Клода — идеальный, чистейший прецедент для нашей Теории Всего. Вы столкнулись не просто с. . .
|
Теория всего 7. Дерево - это патриархат, грибы - это феминизм
anaschu 21.07.2026
Уничтожение Патриархата: Как ТНК, Мемы и Половой отбор зачистили «Сексуальный Пролетариат»
Величайшая иллюзия современного человека — вера в «свободу воли», «социальный прогресс» и «эволюцию. . .
|
История и социология Терры на примере борьбы микориз за пространство. 1. Глоссарий терры.
anaschu 21.07.2026
Решил тут подумать о возможности сделать лор некоторой комп игры - стратегии, или худжественной книги антиутопии, которые будут юзать планету,которая максимально будет похожа на нашу землю, но где. . .
|