Быстрая рандомизация данных (29.08.2026). Печать
2026 - Август
29.08.2026 07:23
Save & Share
Простая стажёрская задачка создать файл с хаотичными данными и посчитать его контрольную сумму - обернулась опять исследованиями.


Как стажёр сделает задачу. Будет в одном цикле сувать функцию rand() - в лучшем случае в файловый поток; потом сопрёт у ИИ какую-нибудь функцию расчёта MD5. Его не волнует уникальность данных. Его не волнует скорость генерации. Он не знает особенностей ОС при такой задаче. Он не будет свои исходники тестировать долго. Фактически, эту задачку нужно на собеседовании давать: эффективно проверяется объём мозга соискателя и/или его опыт.

Задача начинается с выбора среды программирования. Изначально Borland C++ Builder v.6.0 2002 года выбран не просто так, в сравнении с Qt 202x года: было заранее известно, с долгими годами эксплуатации, что Qt - говно. Ну попробуйте в нём перетипировать число с помощью String() - получится феноменальный текстовый однобайтовый результат. Ну попробуйте в нём сгенерировать случайное число - вместо простой интуитивной rand() используется QRandomGenerator::global()->bounded(), которую ещё и инклудить надо (вот как без гугла всё это допереть?). Но оказалось ещё и другое. Предположение подтвердилось: у борланда генерация числа занимает 2-3 такта процессора, у Qt - от 7-15 (самый быстрый) до 1000-5000 (и не уверен, что самый медленный).

Дальше - больше. Кто сказал, что rand() билдера быстрая. И выясняется, что существует куча алгоритмов генерации чисел, которые совместимы с любым C-подобным языком и быстрее встроенной функции rand() более чем в 5 раз (побитовый сдвиг, линейный конгруэнтный генератор LLG, XORShift, предварительно рассчитанные таблицы LUT, ассемблерная вставка ASM). Да можно вообще, если не важна хаотичность чисел (просто уникальность), - банально считывать 8-байтное значение тиков процессора после старта системы с помощью QueryPerfomanceCounter().

Но даже если в файловый поток по 8 байт хреначить - это будет медленно. Предварительные эксперименты на SSD показали (идею дали прошлые эксперименты низкоуровневого чтения и высокоуровневой записи данных у HDD): размер порции для потока (то есть, для носителя) - должен быть не меньше размера его физического сектора. Дальнейшее увеличение порции до размера кластера файловой системы - значимой прибавки в скорости не имеет (тут не уверен: в тесте, вроде, NTFS с её стандартным размером 4КиБ была).

Как считать контрольную сумму: с помощью MD5? Увольте: давно существует быстрый BLAKE3 (и так же просто функциями добавляется в проект). К слову, отказ что от MD5, что от rand(), - привел к отсутствию постоянной загрузки логического процессора на 100%. >80% никогда не поднимался - параллелизм для ускорения работы не требуется.

Зачем это всё было нужно: в WinPE от Стрельца есть 1 противный баг. Если в его RAM-диск с ОС (X:\) кидать файлы - то файлы большого размера портятся сразу после копирования (часть содержимого). Нужно выяснить граничный размер файла и послать разработчику. А также для собственного понимания: что в RAM-диск кидать можно, а что нельзя (полный DVD точно нельзя - именно так этот баг и был найден).

Примерная реализация интернет-мема с воротами (поднять или опустить). Выгодно дописывать часть данных к создаваемому файлу, всё больше наращивая его размер и проверяя контрольную сумму. Но кеширование ОС может испортить результат при копировании на X:\. Но перезапись огромными объёмами исходного файла перед копированием - уменьшает ресурс SSD. Но на HDD это будет работать медленно, и RAM-диска нет.

Можно ли сказать после этого, что я не стажёр? Ну... да. Просто обнаружился баг, который не является багом, и который был пропущен. Тип unsigned long в Linux занимает 8 байтов, а в Windows x32 и x64 - только 4 байта. И при переходе с Linux на Windows это было забыто. Нужно объяснять, что произошло при работе программы, когда цикл перевалил за размер файла 4ГиБ?..

(добавлено 30.08.2026) Для скрытного удалятора удалённого из Ext4 - всё-таки потребуется использовать параллелизм из-за гигантского количества данных.

(добавлено 26.10.2026) Дал тему создания быстрого генератора данных стажёру на диплом. Сам стажёр ничего не может - но, т.к. и моя башка немного крутится в этом направлении, - появились некоторые мысли:
- так как генерируется мусор, есть простая выгода: умножить быстро сгенерированное однобайтовое число на процессорные тики, поделить число на константу миллион-миллиард (породить дробную часть) - и породить мусор double размером 8Б, да ещё и с мантиссой со своим неизвестным алгоритмом представления в битах;
- кто сказал, что вместо double нельзя использовать long double 10-16Б (зависит от среды программирования). Перетипирование медленное - но вдруг выгорит;
- можно идти ещё дальше. Самый быстрый, по мнению гугла, алгоритм расчёта контрольной суммы BLAKE3 - породит от случайного 8-байтного числа double 32Б. А SHA-512 - медленнее, но породит 64Б. На практике тестировать надо всё это на скорость: есть ещё быстрые Adler-32, Луна. BLAKE3 - умеет в многопоточность, но программа-то однопоточная, в которой он запускается, - выгоднее натравить внешнюю утилиту b3sum (с параметром количества ядер ЦП минус 1) на файл с числом и забрать её результат;
- вот я дипломную теорию стажёра и сделал за 10мин...

(добавлено 28.10.2026) Обязательство, как наставника, довести стажёра до необходимой защиты диплома (по теме быстрого генератора данных) и научить его программированию (с нуля: там ни аналитики, ни исходников личных) - тоже аннулировано. Стажёр меня не просто кинул: его экс-стажёр подговорил (см. последние заметки от 22.10.2026 и до конца: это полный сюр, как будто во сне всё происходило).

(добавлено 29.10.2026) Небольшое обновление: практические тесты.

(добавлено 30.10.2026) Часть 3: не могу остановиться.

(добавлено 01.11.2026) Даа, 4-я часть вышла совсем крутой.

(добавлено 02.11.2026) А часть 5 - вышла трешовой, но с правильным результатом.

(добавлено 03.11.2026) Продолжение анализа вопроса: генераторы внутри генераторов.


Ода define.

(добавлено 05.11.2026) (суровый молчаливый взгляд человека, повидавшего некоторое дерьмо)
Обновлено ( 05.11.2026 15:48 )