Сайт TechStop-Ekb.Ru, логотип текстовый.Сайт Тех Стоп Екб Ру, логотип инфографика.

Массив переменных значений по случайному индексу.

Сверх скоростная обработка строк в CMD интерпретаторе.

Как ушатать BAT / CMD интерпретатор. Горе от ума ))) ...

Сегодня я хочу рассказать, как мне удалось снести с катушек выполнение программного сценария BAT / CMD интерпретатора командной строки Windows 7 - при абсолютно исправном коде ))) ... Дело было - так ... Мне понадобилось нагенерить несколько автоматических строчек случайного, но связанного содержания, из предварительно отселектированных текстовых файлов A B C .txt, содержащих соответственно 190, 253 и 198 строковых записей ...

Конечно, можно было их жестко загнать в локализованные переменные !Axn! !Bxn! !Cxn! связанного режима времени выполнения SetLocal EnableExtensions EnableDelayedExpansion - прямо внутри кода скриптового сценария ... Но - не в этот раз : лень надавила на кнопки нейронов ума, и заставила мозг придумать более изящное решение опроса строк текста и заполнения ими - переменных ... Единственной виртуальной рабочей конструкцией, в этом случае, является - массив ...

В BAT / CMD массив не задаётся явной командой, представляя из себя последовательность данных, сгруппированных по имени переменной и её порядковому индексу ... Соответственно, заполнение массива - идет по счётчику и в цикле ...


REM Инициализируем счётчик ... 
	SET Ai=0 
REM Запускаем цикл опроса ... 
	FOR /F "tokens=*" %%A IN (A.dat) DO (
REM Для каждого шага итерации - увеличить счетчик ... 
		SET /A Ai+=1
REM Инициализировать переменную по индексу счётчика и заполнить значением ... 
		SET "mAst[!Ai!]=%%A"
REM Продолжить шаги итерации - до последней строки в файле ... 
)

Массив успешно создан и удобно расположился в оперативной памяти ... Минимум кода в скрипте ... Максимум удовольствия ))) ... Следующий этап - взять случайную строку и вставить ее в предложение, то есть - получить рандомные слова по индексу массива слов ...

!Ai! - переменная уже знает количество всех строк в массиве ...
SET /A RndA=!RANDOM! %%!Ai! +1 - вот это уже сложная конструкция ))) ... ключ /A побуждает установщик SET вычислить случайное значение !RANDOM! , в диапазоне ограниченном значением !Ai! (190) , делением с остатком %% и всегда больше нуля - параметр +1 ... Такая вот сложнейшая команда - делает простейшую вещь - генерирует случайный индекс строки в файле, полное содержимое строк, которого - заранее неизвестно и в любое время - может быть произвольно модифицировано, без последствий на будущие вычисления ...

Это - очень хорошо ... Плохо - другое : не получается получить значение массива A строки !mAst[!RndA!]! - по случайному индексу ... Нет, реальное значение переменной !mAst[5]!= пожалуйста, а виртуальное - извините ))) ...
mAst - это имя переменной, кодирующее сокращение понятия : массив A строка ...

При этом, метод опроса переменных массива, с переменным индексом, в цикле - остаётся работоспособным ...
Команда FOR /L %%K IN (старт, степ, стоп) DO ... - в качестве шага точки может принять - и переменное значение ...
И, вот в этом месте, я допустил ужасную ошибку ... Понимая, что : зная значение виртуального рандомного индекса, чтобы узнать соответствующую ему строку - мне незачем перебирать весь ряд, от 0, +1, и до !RndA! ...
Например, если !RndA! =47 ... то мне нужно опросить диапазон от !RndA! -1 до !RndA!, с обычным шагом = 1 ... (46,1,47) ... Таким образом, достигается - небывалое ускорение обработки программного кода ...


REM Инициализируем переменную начала итерации цикла ... 
	SET /A Stt=!RndA!-1
REM Извлекаем из массива случайную строку по рандомному индексу ... 
	FOR /L %%K IN (!Stt!,1,!RndA!) DO SET OutA=!mAst[%%K]!

Используем полученное слово / строку !OutA! - по требуемому назначению ... Описывать, этот процесс, дальше - уже неинтересно ; теперь - это обычная переменная с фиксированным значением, как a=5 или b=world ))) ... Интересен, был - лишь факт определения её значения ...

Теперь, расширяю секцию кода, чтобы получить четыре случайных слова из списка ... И, саму секцию - повторяю ещё трижды ... А - вру ... четырежды ... Таким образом, имеется ...
три массива A B C, общей численностью 641 строка + ещё массив D на 160 индексов = всего 801 вариант ...
Четыре счетчика ... Четыре перезаписываемых рандомных числа и 16 фиксированных выходных словоформ ... При этом, чудесным и замечательным свойством этой организации текстового генератора является то - что входные списки слов можно изменять произвольным образом ... Менее 1000 переменных, что для компьютера - не должно являться большой проблемой, тем более, явно указав сокращённый диапазон опроса цикла, по идее - должна высвободиться куча памяти и процессорного времени ...

Первые испытания проходили через запуск с флешки и до третьей попытки показывали валидные результаты ... Но, как только значение вывода алгоритма увеличилось до 10 ... А, к слову сказать - планировалось сгенерировать 1000 файлов по 4 предложения ... То, уже на первой десятке - начались неустойчивые сбои в работе генератора фраз, проявляемые, как : продолжение работы кода на экране, но без записи выходных файлов на флеш ...

Первое мнение, было : флешка не успевает за сверх скоростной обработкой интерпретатора CMD и - отваливается ... Тогда - генератор был перенесён на современный высоко скоростной SSD диск, эксперименты были продолжены, но - с тем же неадекватным и непрогнозируемым результатом ... При каждой следующей попытке могло быть записано 10, затем 6, в следующий раз 35 файлов, и далее - происходил срыв / отказ записи файлов на диск, без любых уведомлений о неисправности ))) ...

Тогда я разбил алгоритмы A B C D генерации - по отдельным скриптам и сделал один общий стартующий синхронизирующий файл, который каждый раз открывал скрипт на исполнение - в отдельной новой копии CMD, с завершением, и повторной загрузкой соответствующего массива - каждое следующее открытие ... Таким образом, я добился распределения и разделения выделяемой памяти новым копиям запускаемых сред CMD интерпретаторов и более устойчивой их работы, с некоторым естественным падением в скорости обработки данных ...

Единственной причиной отказов - я предполагал сбои в самом BAT / CMD интерпретаторе : либо он не успевал обрабатывать таблицы ссылок на переменные, либо - не успевал устанавливать селекторы регистров вслед за неожиданно быстрой обработкой CPU ... Поэтому, сам код скрипта - работал на экране, а зависимости, связанные с файловой системой ввода / вывода - отваливались ...

Ранее - я никогда не задавался вопросом, насколько принципиально большая разница между DOS и CMD окном командной строки, в количестве переменных, в объёме выделяемой оперативной памяти, во времени тайм-аутов работы с драйверами дисковой системы ... Думаю, что копать нужно - в этом направлении ... Однако, разделив цельный алгоритм на логические части - общая работоспособность была восстановлена, и ожидаемый результат - получен тютелька в тютельку ))) - так, как это и было запрограммировано ...

Но, именно, столкнувшись с таким нестандартным поведением - я в принципе узнал про неочевидное поведение команд CMD, о котором расскажу в следующей статье ...

Раздел computer : список всех страниц ...