【问题标题】:Performance difference between ASCII characters during an IF comparisonIF 比较期间 ASCII 字符之间的性能差异
【发布时间】:2023-03-07 03:24:01
【问题描述】:

在摆弄了一下时,我发现了这个有趣/令人困惑的发现。因为我真的不知道如何执行准确的批处理文件命令时间测量,至少不在同一个文件中,(但我也很感激有关如何做到这一点的任何帮助),我只有我个人的观察,但很明显,当我在代码中使用点 . 时,它运行得更快。我可以看到enter 提示比使用任何其他普通的单个拉丁 ASCII 字符时快大约半到一秒,例如aRz

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"

此程序用于打开 PDF 文件,这些文件通常集中存储在工作 PC 上,只需输入它们的“名称”即可。

我知道半秒左右,并没有真正做任何事情来制造或破坏它,但我仍然很好奇这怎么可能?在== 字符串比较中,不是所有单个 ASCII 字母的速度都差不多吗?

*更新:在家里试过了,令我惊讶的是,(goto) 2>nul & 部分停止了一起工作。 Exit /B 效果不佳。下一行中只有 Exit 似乎有效。什么??此外,性能差异不再存在,或者我无法从视觉上看到它。现在让我更加困惑的是:在工作时:elsePDF 试图打开一个文件,但显然无法在新创建的文件夹中找到没有文件扩展名的文件,并通过此类提示您出现错误消息;在家里,它会在 Windows 资源管理器中打开“临时”文件夹。 ???两台21H1版本的Win10机器在cmd/bat文件的执行方式上有什么不同?

【问题讨论】:

  • 不确定您是如何通过肉眼判断速度的,我不确定您在 ... 部分运行的其他命令,但这里的速度是一样的。
  • 我的意思是:当使用“.”时它几乎是即时的(看不到没有“输入”文本的命令提示符,当使用任何其他文本时,它需要半秒钟才能出现任何内容(在此之前它是一个空白的命令提示符)。中间应该无关紧要,因为它被跳过对吧?
  • 我不能 100% 确定我得到了你想要达到的目标,在我发布任何答案之前,你为什么 starting 批处理文件?您通常应该 call 它,但在这种情况下,您是在调用文件本身,所以请帮助我了解您的期望。
  • 好的,由于您的扩展,您可以在执行时访问所有内容。 !SystemRoot!!USERPROFILE! 不会改变,您不需要对这些变量运行 delayedexpansion。我还将if !errorlevel! equ 1 更改为if errorlevel 1。您有不需要的代码块。例如:direct 标签下的整个代码块。这些都会导致脚本完成延迟。
  • 实际上,在这个脚本中你甚至根本不需要delayedexpansion。只需删除那些不需要的代码块。

标签: batch-file cmd


【解决方案1】:

在其他条件相同的情况下,比较不同字符时性能没有显着差异。

要准确了解性能,最好通过大量重复该命令来使用较大的样本量。像科学实验一样处理测试任务——每个“实验”只应更改一个变量,以便准确评估该更改的影响。因此,除了您要测试的特定元素之外,代码的每个组件都应该是等价的,以免影响结果。

一个专门测试IF 性能的示例,将字符串
... 与自身与控件sss 与自身进行比较。

@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%

6 次运行的输出:

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

【讨论】:

  • 我对其进行了测试:一次使用...sss,一次使用.s。两次它都由 250 次运行组成(1 次运行 = 1x 点和 1x s('s))。我比较了数据:当数到 100k 所需的时间相同时,我没有计算它。如果它是决定性的(无论利润有多小),我都会给更快的“派对”一个“获胜”点。所以:对于三元组,点有 112 次“胜利”,s 有 105 次“胜利”,单打有 105 次“胜利”,点有 104 次。最短和最长完成时间分别为 4.63 秒和 4.88 秒。
  • 我现在也在工作中对此进行了测试:有趣的发现:运行服务器的文件时(我的问题文件也打开了)从 1 计数到 100k 大约需要 12-13 秒。在桌面上运行它需要 5-6 秒。
  • 这一点也不奇怪。批处理性能会受到多种因素的影响,包括但不限于机器规格、cpu 使用率、环境利用率(IE:定义的变量的数量和大小)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
  • 2021-02-04
  • 2011-10-15
相关资源
最近更新 更多