Тема: CMD/BAT: Нахождение длины строки
Именно такой темы в коллекции нет, хотя в некоторых других темах этот вопрос косвенно подымался. Думаю, что решение данной задачи должно содержаться в коллекции.
Существуют разные способы, как найти длину строки. Рассмотрим их и проведем анализ производительности. В конечном счете выбор должен пасть на самый быстрый вариант решения.
Для замера производительности я использовал следующий шаблон:
@ echo off
setlocal enabledelayedexpansion
call :getTick
set start=%errorlevel%
for /l %%i in (1,1,100) do тут_вызов_функции
call :getTick
set /a long=%errorlevel%-start
echo %long%
pause
exit /b 0
: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%
Т.е. будем запускать функцию определения длины строки 100 раз и замерять время работы. Определять будем длину переменной %Path%, в моем случае она составляет 388 символов - достаточно длинная строка.
Первый вариант решения задачи (решение в лоб):
:length
:: Нахождение длины строки
:: %1 - строка
:: Результат помещается в %errorlevel%
setlocal
set len=0
if "%~1"=="" goto end
set str=%~1
:loop
set /a len+=1
if not "!str:~%len%!"=="" goto loop
:end
endlocal & exit /b %len%
Отработал за 1602, т.е. 16 секунд.
Второй вариант (записываем строку в файл, после чего определяем размер файла):
:length
:: Нахождение длины строки
:: %1 - строка
:: Результат помещается в %errorlevel%
setlocal
:length1
set "tempFolder=%TEMP%\%~n0.%time:~-2%.%random%"
md "%tempFolder%" 2>nul || goto length1
set "tmpFile=%tempFolder%\1"
<nul set /p ".=%1">"%tmpFile%"
for /f %%f in ("%tmpFile%") do set /a "len=%%~zf"
rd /s /q "%tempFolder%"
endlocal & exit /b %len%
Этот вариант отработал за 33, т.е. существенно меньше секунды. Идея создание временного файла взята из обсуждения в этой теме: http://forum.script-coding.com/viewtopic.php?id=7944
Чем же так плох первый вариант? Возможно это связано с циклом goto. В любом случае остановиться надо на втором варианте.