Тема: CMD/BAT: посимвольный перебор строки (сравнение скорости двух методов)
Посимвольный перебор строки можно сделать двумя способами:
1. Завести индекс, брать символ в позиции индекса, инкремировать, проверять на достижение конца строки, goto.
2. Перебирать индекс в for, брать символ в позиции индекса, проверять на достижение конца строки, goto.
Сравним оба варианта на скорость работы:
@echo off
setlocal enabledelayedexpansion
:: Формируем строку из 8000 символов
set "str="
for /l %%i in (1,1,8000) do set "str=!str!A"
:: ===== МЕТОД 1: Доступ по индексу =====
echo Method1:
:: Замер времени начала
call :gettick
set start=%errorlevel%
set idx=0
:loop1
set "ch=!str:~%idx%,1!"
if not defined ch goto end1
rem Тут работа с символом в ch...
set /a idx+=1
goto loop1
:end1
:: Замер времени окончания
call :gettick
set end=%errorlevel%
set /a tm=(%end%-%start%)*10
if %tm% lss 0 set /a tm+=24*3600000
echo Time: %tm% ms
echo.
:: ===== МЕТОД 2: Доступ через цикл for =====
echo Method2:
call :gettick
set start=%errorlevel%
:: 8192 - максимально возможная длина строки в CMD
for /l %%i in (0,1,8192) do (
set "ch=!str:~%%i,1!"
if not defined ch goto end2
rem Тут работа с символом в ch...
)
:end2
call :gettick
set end=%errorlevel%
set /a tm=(%end%-%start%)*10
if %tm% lss 0 set /a tm+=24*3600000
echo Time: %tm% ms
echo.
exit /b
:gettick
:: Количество сотых долей секунды, прошедших с начала дня
setlocal
set t=%time: =0%
set /a tick=1%t:~9,2%-100+(1%t:~6,2%-100)*100+(1%t:~3,2%-100)*6000+(1%t:~0,2%-100)*360000
endlocal & exit /b %tick%Итог на моем компе:
Method1:
Time: 6240 ms
Method2:
Time: 310 msМетод с for быстрее аж в 20 раз!
Вывод: для посимвольного перебора строки выгодно использовать цикл for. Так как заранее не знаем длину строки, то верхнюю границу берем по максимуму, а из цикла выходим по if и goto.
P.S. проверка на пустоту через
if not defined ch goto end1немного быстрее проверки через
if "!ch!"=="" goto end1
