Быстрая рандомизация данных (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 - всё-таки потребуется использовать параллелизм из-за гигантского количества данных.
Обновлено ( 30.08.2026 14:54 )