Which is faster for substring detection, IF !A! !A:B=!, echo.!A!|find "!B!" or echo.!A!|findstr /c:"!B!" ?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
shodan
Posts: 87
Joined: 01 May 2023 01:49

Which is faster for substring detection, IF !A! !A:B=!, echo.!A!|find "!B!" or echo.!A!|findstr /c:"!B!" ?

#1 Post by shodan » 24 May 2024 00:30

Answer IF !A! !A:B=! is 4 times faster than the other two
10000 loops of the IF takes about 45 seconds, no matter how long the strings are, while the other two take about 2 minute and a half !

-----------------------------------

Since I am writing a GetIndexSubstring and am still optimizing it.

I wanted to know which of these three methods to check if a string is inside another string was the fastest

So I wrote the following code to test

Code: Select all

:IF-versus-FINDSTR
setlocal enabledelayedexpansion
Set "_IVF_Input=THIS IS a TEST"
Set "_IVF_Search=IS"
Set /a _IVF_count=10000
set "_IVF_callback_label=:IF-versus-FINDSTR-1"
GoTo :IF-versus-FINDSTR-loop-start
:IF-versus-FINDSTR-1
Set "_IVF_Input=THIS IS a TEST with many characters 012345689[7000 characters removed here for brevity]012345689"
Set "_IVF_Search=IS"
Set /a _IVF_count=10000
set "_IVF_callback_label=:IF-versus-FINDSTR-2"
GoTo :IF-versus-FINDSTR-loop-start
:IF-versus-FINDSTR-2
:IF-versus-FINDSTR-3
:IF-versus-FINDSTR-4
GoTo :EOF
:IF-versus-FINDSTR-loop-start
Set /a _IVF_index=1
echo start IF TEST %time% count %_IVF_count% search %_IVF_Search% input %_IVF_Input%
:IF-versus-FINDSTR-loop
set "_IVF_buffer=!_IVF_Input:%_IVF_Search%=!
if !_IVF_Input! EQU !_IVF_buffer! ( set "_IVF_result=true" ) else ( set "_IVF_result=false" )
Set /a _IVF_index+=1
if %_IVF_index% LSS %_IVF_count% GoTo :IF-versus-FINDSTR-loop
echo end IF TEST %time% count %_IVF_count% search %_IVF_Search% input %_IVF_Input%
:IF-versus-FIND-loop-loop-start
Set /a _IVF_index=1
echo start FIND TEST %time% count %_IVF_count% search %_IVF_Search% input %_IVF_Input%
:IF-versus-FIND-loop-loop
echo.!_IVF_Input!| find "!_IVF_Search!" >nul && ( set "_IVF_result=true" ) || ( set "_IVF_result=false" )
Set /a _IVF_index+=1
if %_IVF_index% LSS %_IVF_count% GoTo :IF-versus-FIND-loop-loop
echo end FIND TEST %time% count %_IVF_count% search %_IVF_Search% input %_IVF_Input%
:IF-versus-FINDSTR-loop-loop-loop-start
Set /a _IVF_index=1
echo start FINDSTR TEST %time% count %_IVF_count% search %_IVF_Search% input %_IVF_Input%
:IF-versus-FINDSTR-loop-loop-loop
echo.!_IVF_Input!| findstr /c:"!_IVF_Search!" >nul && ( set "_IVF_result=true" ) || ( set "_IVF_result=false" )
Set /a _IVF_index+=1
if %_IVF_index% LSS %_IVF_count% GoTo :IF-versus-FINDSTR-loop-loop-loop
echo end FINDSTR TEST %time% count %_IVF_count% search %_IVF_Search% input %_IVF_Input%
GoTo %_IVF_callback_label%
endlocal
GoTo :EOF
And the console output is

Code: Select all

start IF TEST  2:11:42.63 count 10000 search IS input THIS IS a TEST
end IF TEST  2:12:27.97 count 10000 search IS input THIS IS a TEST
start FIND TEST  2:12:27.97 count 10000 search IS input THIS IS a TEST
end FIND TEST  2:15:04.46 count 10000 search IS input THIS IS a TEST
start FINDSTR TEST  2:15:04.46 count 10000 search IS input THIS IS a TEST
end FINDSTR TEST  2:17:32.97 count 10000 search IS input THIS IS a TEST
start IF TEST  2:17:32.97 count 10000 search IS input THIS IS a TEST with many characters 012345689[OUTPUT TRUNKATED HERE]012345689
end IF TEST  2:18:18.84 count 10000 search IS input THIS IS a TEST with many characters 012345689[OUTPUT TRUNKATED HERE]012345689
start FIND TEST  2:18:18.84 count 10000 search IS input THIS IS a TEST with many characters 012345689[OUTPUT TRUNKATED HERE]012345689
end FIND TEST  2:20:50.41 count 10000 search IS input THIS IS a TEST with many characters 012345689[OUTPUT TRUNKATED HERE]012345689
start FINDSTR TEST  2:20:50.41 count 10000 search IS input THIS IS a TEST with many characters 012345689[OUTPUT TRUNKATED HERE]012345689
end FINDSTR TEST  2:23:29.77 count 10000 search IS input THIS IS a TEST with many characters 012345689[OUTPUT TRUNKATED HERE]012345689


Aacini
Expert
Posts: 1888
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Which is faster for substring detection, IF !A! !A:B=!, echo.!A!|find "!B!" or echo.!A!|findstr /c:"!B!" ?

#3 Post by Aacini » 24 May 2024 09:38

The answer is obvious (with no test): in echo !A!|find "!B!" construct there is a pipe that imply the execution of two copies of cmd.exe file, one of which in turn must load and execute find.exe file. In IF "!A!" NEQ "!A:%B%=!" there is nothing additional that needs to be loaded from disk, so the execution entirely happens in memory (much faster).

Antonio

Post Reply