0

When fiddling around a bit, I made this interesting/confusing discovery. As I don't really know how to perform an accurate batch file command time measurement, at least not in the same file, (but I'd appreciate any help with how to do that too), I only have my personal observations, but it is quite noticeable that when I use a dot, ., in my code, that it runs faster. I can see the enter prompt at around half to one second faster than when I use any other normal single latin ASCII character, e.g. a, R, z etc.

vw-xyz.bat

@echo off
setlocal EnableExtensions
setlocal EnableDelayedExpansion



    Title xyz

    set "arg1=%~1"
    if "%arg1%"=="R" goto DIRECT
    
    if not exist "!USERPROFILE!\Desktop\temp\" (
        mkdir "!USERPROFILE!\Desktop\temp\"
        attrib +h "!USERPROFILE!\Desktop\temp"
        !SystemRoot!\System32\xcopy.exe "temp-xyz.bat" "!USERPROFILE!\Desktop\temp\" >nul 2>nul
    )

    for /r %%a in (*.pdf) do (
        !SystemRoot!\System32\xcopy.exe "%%a" "!USERPROFILE!\Desktop\temp\" /D /I /Y /Z >nul 2>nul
    )



:DIRECT
    (
    cls
    set /p UserInput=enter xyz: ..
    !SystemRoot!\System32\ping.exe -n 1 xyzServer >nul 2>nul
    IF !ERRORLEVEL! NEQ 0 (start "" "!USERPROFILE!\Desktop\temp\temp-xyz.bat" & EXIT /B) else (break)
    )

    !SystemRoot!\System32\taskkill.exe /F /IM "msedge.exe" >nul 2>nul
    !SystemRoot!\System32\timeout.exe /T 1 /NOBREAK >nul 2>nul

    IF /I "!UserInput!"=="update" (goto UPDATE) else (goto NORMAL)



:UPDATE
    !SystemRoot!\System32\ping.exe -n 1 xyzServer | !SystemRoot!\System32\findstr.exe /r /c:"[0-9] *ms"
    rmdir /s /q !USERPROFILE!\Desktop\temp >nul 2>nul
    (goto) 2>nul & call vw-xyz.bat



:NORMAL
    if exist "!USERPROFILE!\Desktop\temp\!UserInput!.pdf" (goto PDF1)
    if exist "!USERPROFILE!\Desktop\temp\000000!UserInputID!.pdf" (goto PDF2)
    if exist "!USERPROFILE!\Desktop\temp\000000-!UserInputID!.pdf" (goto PDF3) else (goto elsePDF)

    :PDF1
    start "" /MAX "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" -inprivate file:///"!USERPROFILE!\Desktop\temp\!UserInput!.pdf" 
    goto RESUME

    :PDF2
    start "" /MAX "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" -inprivate file:///"!USERPROFILE!\Desktop\temp\000000!UserInput!.pdf" 
    goto RESUME

    :PDF3
    start "" /MAX "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" -inprivate file:///"!USERPROFILE!\Desktop\temp\000000-!UserInput!.pdf" 
    goto RESUME

    :elsePDF
    start "" "!USERPROFILE!\Desktop\temp\!UserInputID!" >nul 2>nul
    goto RESUME



:RESUME
    IF !ERRORLEVEL! EQU 0 (break) else (goto DIRECT)

    cls
    !SystemRoot!\System32\timeout.exe /T 4 /NOBREAK >nul 2>nul
    (goto) 2>nul & start "" vw-xyz.bat "R"

This program is used to open PDF files, which are normally centrally stored on a working PC, by entering their 'name'.

I know that the half second, or so, doesn't really do anything to make or break it, but I'm still curious as in how can this be? Shouldn't all single ASCII letters be about the same speed in a == string comparison?

*Update: Tried it at home and here to my surprise the (goto) 2>nul & part stopped working all together. Exit /B didn't work as well. Only a Exit in the next line seems to work. what?? Also the performance difference isn't there anymore or it is that small that I cannot see it visually. And to add to my absolute confusion now: When at work :elsePDF tries to open a file but obviously cant find a file without file extension in a newly created folder and through such prompts you with an error message; at home it opens the 'temp' folder in windows explorer. ???? How can two Win10 Machines with version 21H1 differ in how cmd/bat files are executed?

  • Not sure how you are judging by eye the speed and I am not sure what other commands you're running in the `...` sections, but speed is the same here. – Gerhard Nov 30 '21 at 12:12
  • by eye I mean: when using the "." it is near instant (cant see the command prompt without the "enter" text and when using any other it takes like half a second before anything appears (before that it is a blank command prompt). The in between shouldnt matter as it is skipped, right? – UserPo41085 Nov 30 '21 at 12:18
  • I am not 100% sure I get what you are trying to achieve, before I can post any answers, why are you `start`ing a batch file? You should `call` it generally, but in this case you are calling the file itself, so help me understand your expectations. – Gerhard Nov 30 '21 at 12:45
  • I updated the code to the whole code in use, dk if you already saw that, disregarding that: Im starting the whole thing after the 4 seconds delay so it is in focus after the pdf opened, and I dont think(?) this is possible when `calling` a bat file. – UserPo41085 Nov 30 '21 at 12:49
  • 3
    ok, so you are accessing everything at execution time because of your expansions. `!SystemRoot!`, `!USERPROFILE!` does not change and you don't need to run `delayedexpansion` on those variables. I would also change `if !errorlevel! equ 1` to `if errorlevel 1`. You have code blocks where they are not needed. for instance the entire code block under `:direct` label. These will all contribute to delayes in script completion. – Gerhard Nov 30 '21 at 12:56
  • 3
    in actual fact, you don't even need `delayedexpansion` at all in this script. just remove those unwanted code blocks. – Gerhard Nov 30 '21 at 13:05
  • @Gerhard I use `delayedexpansion` and code blocks mostly for the fact that as i have read here [link](https://stackoverflow.com/a/37940551/16963475) you need both so the part below `set /p` in `:direct` works, namely ping for server availability and act upon failure, as the file itself is on the server and cant access itself anymore. For that i used this idea of caching everything necessary so it would work, regardless of connection. Before you may ask: I built this in bc it is not uncommon for the program to be in this "waiting state" at `set /p` for longer periods of time without use. – UserPo41085 Nov 30 '21 at 20:29
  • You only require `delayedexpansion` when you require `set`ting a vairable and using it at execution time. Code blocks are needed for when they are needed, so do a few things `if` or in a `for` loop. For now, you can remove the outer code block in the `direct` label and switch of `delayedexpansion`. As you say they work, but you are complicating things with `delayedexpansion` where it is not required at all `:)` – Gerhard Nov 30 '21 at 20:37

1 Answers1

0

All other things being equal, there is no significant difference in performance when comparing different characters.

To get an accurate idea of performance, it's best to use a large sample size by repeating the command a significant number of times. Approach the task of testing like you would a scientific experiment - with each 'experiment' only one variable should be changed in order to accurately assess the impact of that change. Hence, every component of your code apart from the specific element you aim to test should be equivilant so as not to intefere with the result.

An example of testing specifically the performance of IF comparing the string
... against itself, vs the control sss against itself.

@Echo off

Echo(%time%
For /l %%i in (1 1 100000)Do If "..."=="..." Rem.
Echo(%time%
For /l %%i in (1 1 100000)Do If "sss"=="sss" Rem.
Echo(%time%

The output of 6 runs:

21:35:15.36
21:35:20.44
21:35:25.50

21:35:58.33
21:36:03.36
21:36:08.36

21:36:10.47
21:36:15.47
21:36:20.47

21:36:22.41
21:36:27.40
21:36:32.41

21:36:34.55
21:36:39.55
21:36:44.56

21:36:46.67
21:36:51.66
21:36:56.66
T3RR0R
  • 2,565
  • 3
  • 9
  • 22
  • I tested it: One time with `...` and `sss` and one time with `.` and `s`. Both times it was composed of 250 runs (1 run = 1x the dot(s) and 1x the s('s)). And i compared the data: when the time needed to count up to 100k was the same i did not count it. If it was decisive (no matter how small the margin) i gave the "party" that was faster a point for "winning". So: with the triples there were 112 "wins" for the dots and 105 for the s's with the singles there were 105 "wins" for the dot and 104 for the s. With a min and max completion time of of 4,63s & 4,88s respectively. – UserPo41085 Nov 30 '21 at 20:15
  • I tested this at work now too: Interesting find: When running the file of of the server (my question file is also on) one count from 1 to 100k takes about 12-13s. When running it on the desktop it takes 5-6s. – UserPo41085 Dec 01 '21 at 13:26
  • This is not surprising in the least. batch performance can be affected by a number of factors, including but not limited to Machine specs, cpu usage, degree of environment utilisation (IE: number and size of variables defined) – T3RR0R Dec 01 '21 at 14:37