Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
 Аватар для Evil12Boy
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
.NET 7

Как быстро определять наличие строк в файле, при этом не засоряя ОЗУ?

25.10.2023, 22:55. Показов 3910. Ответов 45
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть код, который находится в цикле. Мне нужно при каждой генерации проверять, есть ли сгенерированная строка в файле. Если есть, записать в другой файл. Раньше делал так:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool F = true;
HashSet<string> HS = new(File.ReadAllLines(path)); //Здесь загружается файл размером 390Мб
Random rnd = new();
string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
int Length= 39;
while (F)
{
  StringBuilder sb = new(Lenght - 1);
  int Position = 0;
  for (int i = 0; i < Lenght; i++)
  {
    Position = rnd.Next(0, Alphabet.Lenght - 1);
    sb.Append(Alphabet[Position]);
  }
  Console.WriteLine(sb);
  if (HS.Contains(sb.ToString())
  {
    F = false;
    //Запись строки в другой файл
  }
}

Вот несколько строк из файла (все они одинаковой длины):
Кликните здесь для просмотра всего текста

fd512f88908e949f7f07c99167799a075c274f1
ff0a33055ea4e6669a3925a94e0a28fb256be5d
99dc7be5c1c761f3f4a0249309a6786fa91d0fb
909fd0f1dcb3149e764212d8279a1d2bc687028
ec4c98b0745d3d7095b85c2d57bafd6befd8681
fb5252617abc7bf0adfc19b0aeb1d8adfb27fd4
8d6f71698b00693009d18c6ed6fae3733932078
17d855fc899e183f150ddf52269d3781f6bbbfb
618512eaf1f16364eecdf63e7de46d3e972e568
0ade12db0026cafb67a2717484e4bb02e40f2f3
c5017274e5bc5c3ca1c9ba7dc19fe8341aa9134
ce5d60fef69ed01a2245084dbeaee4a69ae4afa
7b62f067bd38af3735299df0ba68a11bec52966
...

Но такой метод не вариант, жрёт слишком много ОЗУ (получается ~1,7 Гб занятой ОЗУ из 391 Мб файла). А мне нужно будет использовать файл размером до 2,5Гб.

Также пробовал использовать алгоритм - фильтр Блума из ГитХаба:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Filter<string> filter = new(9999999); 
StreamReader sv = new StreamReader(path);
string line = sv.ReadLine();
while (line != null)
{
  filter.Add(line);
  line = sv.ReadLine();
}
sv.Close();
//Дальше та же генерация строк, проверку делал так:
if (filter.Contains(sb.ToString())
{
  F = false;
  //Запись строки в другой файл
}


Но при использовании файла размером ~2Гб (более 50 млн строк) происходит слишком много ложный срабатываний.

Что предложите делать? Хочется, чтобы результат был - "Да, такая строка точно есть в файле, записываем", а не как с фильтром Блума
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.10.2023, 22:55
Ответы с готовыми решениями:

Как определять наличие символов в тексте
крч поступает message.text в виде str, и надо создать чтобы если она кончается на &quot;.&quot; то она стиралась и далее присваивался для...

Проверка на наличие двух одинаковых строк в файле
Всем привет. Входной файл Input.txt выглядит примерно следующим образом: Первая цифра показывает сколько значений было считано....

Проверить наличие всех нужных строк в файле
Добрый день! Подскажите что использовать чтобы решить данную задачу: Есть файл /etc/audit/audit.rules. Нужно проверить если ли в...

45
 Аватар для Andrey-MSK
3376 / 2262 / 388
Регистрация: 14.08.2018
Сообщений: 7,671
Записей в блоге: 4
27.10.2023, 15:11
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Usaga Посмотреть сообщение
Так код этого проекта открой и глазами посмотри на алгоритм.
Это если код есть, а если только приложение?
0
Эксперт .NET
 Аватар для Usaga
14370 / 9471 / 1360
Регистрация: 21.01.2016
Сообщений: 35,741
27.10.2023, 15:16
Andrey-MSK, проект на питоне...
0
 Аватар для Andrey-MSK
3376 / 2262 / 388
Регистрация: 14.08.2018
Сообщений: 7,671
Записей в блоге: 4
27.10.2023, 15:25
Цитата Сообщение от Usaga Посмотреть сообщение
проект на питоне...
А, ну да
Evil12Boy, Вот вам запрос для БД на вставку данных, которых нет в другой таблице. Можете запускать раз в 5 секунд, а строки генерить в таблицу MyTable01
T-SQL
1
2
3
4
5
6
7
8
9
10
11
INSERT INTO 
    MyTable (MyField)
SELECT 
    MyField01
FROM 
    MyTable01
EXCEPT 
SELECT 
    MyField
FROM 
    MyTable
1
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
27.10.2023, 16:30
Evil12Boy, для 2Гб файла сколько нужно будет сделать проверок и за какое время?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
27.10.2023, 18:00
Цитата Сообщение от Evil12Boy Посмотреть сообщение
Моё приложение будут запускать другие пользователи. Поэтому приложение должно быть и x64, и x32.
Уже много лет не встречал ни единого случая использования 32-х битной ОС которая не способна запускать 64-х битные приложения...
0
 Аватар для Evil12Boy
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
27.10.2023, 18:40  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
сколько нужно будет сделать проверок и за какое время?
Одна проверка одной сгенерированой строки осуществляется один раз по всем строкам файла, желательно за очень короткое время (до милисекунд). На брутфорс похоже)
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
27.10.2023, 18:59
Evil12Boy, генерировать єтих строк для проверки вьі сколько будете? Одну?

Милисекунду на 2Гб -- очень маловероятно даже для озу, придеться строить древо что дополнительно сьест память.
0
 Аватар для Evil12Boy
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
27.10.2023, 19:40  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
генерировать єтих строк для проверки вьі сколько будете? Одну?
Милионы, пока не будет совпадений.
Цитата Сообщение от Wolfdp Посмотреть сообщение
Милисекунду на 2Гб -- очень маловероятно даже для озу
Почему же? Фильтр Блума и HyperLogLog как пример. Но эти алгоритмы не могут сказать на 100%, что строка есть в файле.
Ну и я дал ссылку на хабр пару сообщений назад, сейчас пытаюсь именно это реализовать, но чувствую знаний не хватит(

Добавлено через 14 минут
Цитата Сообщение от Usaga Посмотреть сообщение
Т.е. у тебя есть пользователи на Windows 8.1? Или что? У тебя есть какие-то свидетельства того, что хоть какая-то часть твоей целевой аудитории - бомжи, на древнем собранном на помойке железе?
Прикинь есть. Даже больше скажу, я лично знаком с людьми, которые сейчас сидят на петимуему и юзают виндовс ХП. И им нормально.

Добавлено через 30 секунд
Цитата Сообщение от Usaga Посмотреть сообщение
проект на питоне...
Он зашифрован, кода нету, только программа. Так сказать пример)
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
27.10.2023, 19:51
Цитата Сообщение от Evil12Boy Посмотреть сообщение
кода нету, только программа
Программа на питоне это и есть исходный код...
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
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
27.10.2023, 21:43
Цитата Сообщение от kotelok Посмотреть сообщение
накладные расходы памяти на указатели этих массивов (и на словарь) будут незначительными
Я бы не был так уверен в этом. Обычно подобные манипуляции как раз таки увеличивают потребление памяти. Особенно если использовать ссылочные типы вроде массивов...
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
27.10.2023, 21:49
Someone007,
Тут ведь совершенно конкретный случай с конкретными цифрами. Вряд ли накладные расходы всего на 3844 массивов превысят те 120МБ, которые были сэкономлены на размере самих буферов. Да и один словарь тоже много памяти не займёт. Да, там внутри, насколько помню, при таком наборе ключей, будет выделена память под 3844 корзины (под каждый уникальный ключ), но опять же, не может всё это вместе аж 120МБ потребовать.

Ну и если "индексировать" только по одному байту, то там всего 62 массива получается, а прирост скорости сразу более, чем в 100 раз, чем если каждый раз по всему изначальному буферу искать.
0
 Аватар для Evil12Boy
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
27.10.2023, 21:52  [ТС]
Я отметил ответ, хотя это и не подходит под мои цели (но человеку всё равно очень благодарен за попытку помочь ). Буду и дальше использовать либо фильтр Блума, либо поищу другие алогоритмы, либо банально через HashSet<string>. Отметил ответ потому, что уже полностью убедился в том, что не найду здесь нужного мне ответа. И виноват в этом исключительно я)
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
28.10.2023, 01:09
Цитата Сообщение от Evil12Boy Посмотреть сообщение
хотя это и не подходит под мои цели
Да вам похоже ничего не подходит... Хотя описана вполне рабочая схема для вашего use case...
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
28.10.2023, 04:35

Не по теме:

Хвост мудрейшей Хоро, чем я занимаюсь?! Нет, чтобы спокойно задротить в геншин...



Итак, сейчас будет магия вне Хогвартса, так что за последствия не отвечаю. А если серьезно:
1. у нас словарь из 62 символов. Т.е. мы можем упаковать в 1 байт 4 таких символа
2. у нас вроде как одинаковая длина символов. На этом тоже можно "оптимизировать" проходы, когда конвертнем всё в тупо массив байт. В целом, если приспичит, вопрос решаемый с помощью нулевого разделителя (но просядет скорость).

Сначала формирую файл для опытов. Как-то так (я так и не понял 39 символов или 38, остановлися на 38, но конкретно длина погоды не делает)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System.Text;
 
string source = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
var random = new Random();
var length = 38;
var indexes = new byte[length];
var arr = new char[length];
 
const long size = 1024L * 1024 * 1024 * 3;
 
using var file = new StreamWriter(@"E:\anime temp\big", false, Encoding.UTF8);
var i = 0L;
 
 
while (file.BaseStream.Position < size)
{
    file.WriteLine(Genareate());
}
 
string Genareate()
{
    random.NextBytes(indexes);
    for (var i = 0; i < length; i++)
    {
        arr[i] = source[indexes[i] % length];
    }
    return new string(arr);
}
Теперь реализуем следующее:
- метод, позволяющий перегнать string в byte[], который будет "упакованый в меньший размер" ( в примере ниже это класс NyaConvertor)
- считывание из файла в ОЗУ в виде недоиндекса (как предложил kotelok) Это блок Dictionary<byte, byte[]> ReadAllFile()
- поиск входной строки по этому самому кешу (строку предварительно тоже переганяем в сжатый формат)

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
using System.Collections;
using System.Diagnostics;
using System.Text;
 
const string fileName = @"E:\anime temp\big";
const int countItaration = 50_000;
var encoding = Encoding.UTF8;
 
var itemSource = new InputValueSource(countItaration);
Test(Nya, "финальный прогон");
 
Console.WriteLine();
Console.WriteLine("Nya!");
Console.ReadKey();
 
void Test(Action action, string name)
{
    Console.WriteLine();
    var sw = Stopwatch.StartNew();
    action();
    sw.Stop();
    Console.WriteLine($"{name} - {sw.Elapsed}");
}
 
void FindedAction(string line) { Console.WriteLine(line); }
 
void Nya()
{
    Dictionary<byte, byte[]> ReadAllFile()
    {
        using var file = new StreamReader(fileName, encoding);
 
        var dic = new Dictionary<byte, MemoryStream>();
 
        try
        {
            string? line;
 
            while ((line = file.ReadLine()) != null)
            {
                var arr = NyaConvertor.ToBytes(line);
                var key = arr[0];
                MemoryStream? memory;
                if(!dic.TryGetValue(key, out memory))
                    dic[key] = memory = new MemoryStream();
                memory.Write(arr, 1, arr.Length - 1);
            }
 
            return dic.ToDictionary(x => x.Key, x => x.Value.ToArray());
        }
        finally
        { 
            foreach(var m in dic.Values)
                m.Dispose();
        }
    }
 
    var cache = ReadAllFile();
    GC.Collect();
 
    var skeepSize = NyaConvertor.GetCacheSize(Settings.WordSize);
    foreach (var searchLine in itemSource)
    {
        var word = NyaConvertor.ToBytes(searchLine);
 
        if (cache.TryGetValue(word[0], out var memory))
        {
            var indexWord = 1;
            for (var i = 0; i < memory.Length;)
            {
                if (memory[i] == word[indexWord])
                {
                    indexWord++;
                    i++;
                    if (indexWord == word.Length)
                    {
                        FindedAction(searchLine);
                        break;
                    }
                }
                else
                {
                    i += skeepSize - indexWord;
                    indexWord = 1;
                }
            }
        }  
    }
}
 
static class Settings
{ 
    public static readonly string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
    public const int WordSize = 38;
}
 
class InputValueSource : IEnumerable<string>
{
    private const int wordSize = Settings.WordSize;
    private static readonly Random random = new();
    private static byte[] indexes = new byte[wordSize];
    private static char[] arr = new char[wordSize];
    private readonly IReadOnlyCollection<string> _items;
 
    public InputValueSource(int size)
    {
        var items = new string[size];
        for (var i = 0; i < size; i++)
            items[i] = Genareate();
        //items[0] = "MEgEYPSLOLSOZYPlbMVOQajJaWGVbBFefJWGVV";
        //items[10] = "MEgEYPSLOLSOZYPlbMVOQajJaWGVbBFefJWGVe";
        //items[20] = "aMCZGSWUJbeHjcBTRJMaeWdhfAfgZUcFbfMVHP";
        //items[30] = "YgEbPYTgMhCBIRhGWHCObSQPUIaUQFMEMXjhCa";
        _items = items;
    }
 
    public IEnumerator<string> GetEnumerator()
        => _items.GetEnumerator();
 
    IEnumerator IEnumerable.GetEnumerator()
        => _items.GetEnumerator();
    private static string Genareate()
    {
        random.NextBytes(indexes);
        for (var i = 0; i < wordSize; i++)
        {
            arr[i] = Settings.Alphabet[indexes[i] % wordSize];
        }
        return new string(arr);
    }
}
 
static class NyaConvertor
{
    private static readonly IReadOnlyDictionary<char, byte> _dic;
 
    static NyaConvertor()
    {
        var dic = new Dictionary<char, byte>();
 
        byte val = 1;
        foreach (var c in Settings.Alphabet)
        {
            dic.Add(c, val++);
            if (val > 64)
                throw new Exception("невозможно сжать данные");
        }
 
        _dic = dic;
    }
 
    public static byte[] ToBytes(string input)
    {
        var output = new byte[GetCacheSize(input.Length)];
        var iteration = 0;
        var buff = 0;
        var i = 0;
        foreach (var c in input)
        {
            buff = (buff << 4) | _dic[c];
 
            iteration++;
            if (iteration == 4)
            {
                iteration = 0;
                output[i++] = (byte)buff;
            }
        }
 
        if(iteration != 0)
            output[i] = (byte)buff;
 
        return output;
    }
 
    public static int GetCacheSize(int inputSize)
        => inputSize / 4 + (inputSize % 4 > 0 ? 1 : 0);
}
Итого:
- формирование кеша из 3Гб занимает ~1минуту (проверял в Release сборке)
- кеш отьедает менее 3Гб ОЗУ. Тестировал на х86 -- вроде не падало
- что 50, что 50к строк для поиска проглатывает моментально. Надо по хорошему замерить сколько именно ищет, без учета формирования кеша, но это уже без меня.
- для 300Мб я бы выкинул упаковку кеша, просто считал как есть в ОЗУ или около того.
- если с памятью вообще притык -- тут только скидывать на файлы. Можно заморочится, чтобы кеш был "умным" и подгружал по необходимости... без меня.

В целом, если вам нужно один раз загрузить файл в память, а потом ооооочень много раз (эдак 1кк, не меньше) к нему обращаться -- вариант рабочий.


P.S.
В целом код на 99% состоит из идей kotelok + упаковка. Была попытка замерить "сразу за один проход искать N-строк, а не одну", но почему-то такой подход ещё медленее, чем по одной строке. Ну либо профит начинается с 1к записей, а ждать 100500 часов желания нет.

по "фильтр Блума" из того же Хабра
Важно понимать, что фильтр Блума — это вероятностная структура данных: он может сказать вам со 100% вероятностью, что элемент отсутствует в наборе данных, но сказать со 100% вероятностью, что элемент находится в наборе, он не может
На русском:
- если мы НЕ НАШЛИ вхождение, значит его 100% нет
- если мы НАШЛИ вхождение, то это не означает что элемент реально входит, а не тупо колизия. На 80+ лямах записи -- вообще никаких гарантий.

По поводу "там есть программа, которая юзает 10Мб".... Ну, не знаю что там за колдунство, но вот простой вопрос -- как можно инфу на 3ГБ перегнать в 10Мб без потерь? Либо там таки работа с временными файлами, либо алгоритм делает что-то другое. Чудес как правило не бывает.
3
 Аватар для Evil12Boy
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
28.10.2023, 13:21  [ТС]
Wolfdp, очень благодарен! Буду пока-то использовать именно это (HashSet и фильтр Блума теперь нервно курят в стронке). А что вы можете сказать на счёт алгоритмов Boyer–Moore`а и Rabin–Karp`а ?

Добавлено через 47 секунд
Цитата Сообщение от Wolfdp Посмотреть сообщение
NyaConvertor
Ня-конвертор, потешно))
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
28.10.2023, 14:10
Цитата Сообщение от Evil12Boy Посмотреть сообщение
А что вы можете сказать на счёт алгоритмов Boyer–Moore`а и Rabin–Karp`а ?
К сожалению ничего, впервые о них слышу.

На всякий -- перепроверте работоспособность кода, т.к. тестировал бегло. Также учтите что кеш считывался с М.2 SSD диска и системы где явно избыток ОЗУ. В реальности на WindowsXP (которая в целом видит только 3ГБ оперативки) и на HDD это будет выглядеть не столь бодро.
0
 Аватар для Evil12Boy
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
28.10.2023, 16:20  [ТС]
Код работает нормально (хотя запускал тоже на m.2 ssd), на более слабом железе протестирую позже. А сейчас я хочу испробовать два новых алгоритма, мне кажется алгоритм Карпа (при правельной реализации) именно то, что мне нужно)
0
 Аватар для Evil12Boy
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
29.10.2023, 00:39  [ТС]
М-да . . . Отсортировал я файл (391 Мб) по алфавиту (кнопка F9 в Sublime Text и готово).
Дальше нашел реализацию бинарного поиска на питоне.
Цитирую автора скрипта:
Кликните здесь для просмотра всего текста

у меня поиск занимает около полторы тысячных секунды на файле 2ГБ с 46.6 миллионами случайных строк длиной 40-50 символов каждая.

Вот код:
Кликните здесь для просмотра всего текста

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import mmap
import os
import sys
 
eol_bytes = list(enumerate(os.linesep.encode('utf-8')))
 
def is_eol(mm, i, size):
    return i + len(eol_bytes) <= size \
        and all(b == mm[i + n] for n, b in eol_bytes)
 
def binarySearch(mm, l, r, x, size):
    eol_bytes = os.linesep.encode()
    x = x.encode()
    while l <= r:
        mid = l + (r - l)//2
        prev_eol = mm.rfind(eol_bytes, 0, mid + len(eol_bytes))
        if prev_eol == -1: prev_eol = 0
        next_eol = mm.find(eol_bytes, mid + 1)
        if next_eol == -1: next_eol = size
        pos = prev_eol+len(eol_bytes) if eol_bytes == mm[prev_eol:prev_eol+len(eol_bytes)] else prev_eol
        mid_slice = mm[pos:next_eol]
        if mid_slice == x:
            return pos
        elif mid_slice < x:
            l = next_eol + len(eol_bytes)
        else:
            r = prev_eol
    return -1
 
with open('file.txt', 'r+b') as f:
    s = 0
    mm = mmap.mmap(f.fileno(), 0)
    f.seek(0, os.SEEK_END)
    size = f.tell()
    while True:
        result = binarySearch(mm, 0, size, 'fffffb3c80d1f98ef97464bce0e3c9344e4e6a9', size)
        if result != -1:
            s = s + 1
            print("Number of successful checks: ", s)
        else:
            break

Скорость - предостаточная. ОЗУ не нагружает вообще.
Остаётся написать подобное на C# и это то, что я искал)
0
 Аватар для Evil12Boy
0 / 0 / 0
Регистрация: 25.10.2023
Сообщений: 35
29.10.2023, 16:33  [ТС]
Лично у меня не получилось переписать код из Python в C#
Никогда не приходилось работать с MemoryMappedFiles
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.10.2023, 16:33

Как быстро проверить массив на наличие равных элементов
Можно написать такую функцию: int busy(int j) { foreach (i; 0 .. j) if (a == a) return 0; return 1; } Но меня...

Опишите алгоритм, позволяющий быстро вычислить код при этом не использующий числа превышающих 2^32
программист Иванов постоянно меняет 5-значный код на велосипедном замке. Ежедневно вычисляет код так: возводит текущую дату в формате...

Как при открытии этого файла сделать что бы он загружал мой редактор и с текстом находящейся в этом файле?
Помогите: 1) Сделал текстовой редактор. 2) Сделал свой тип файла с расширением например 'ss'. Вопрос: Как при открытии этого файла...

Ввести данные слов в N строк в файл и сделать сортировку по алфавиту в этом файле
Всем привет, требуется: 1. Создать файл; 2. Узнать кол-во строк для заполнения данными(фамилия, имя,группа); 3. Записать данные для...

Подсчет количества строк в текстовом файле, имя которого задано первым параметром КФ. Проверить наличие указа
Подсчет количества строк в текстовом файле, имя которого задано первым параметром КФ. Проверить наличие указанного файла и вывести...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Теория всего 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
Решил тут подумать о возможности сделать лор некоторой комп игры - стратегии, или худжественной книги антиутопии, которые будут юзать планету,которая максимально будет похожа на нашу землю, но где. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru