代码之家  ›  专栏  ›  技术社区  ›  Mofi

为什么GOTO循环比FOR循环慢得多,而且还依赖于电源?

  •  3
  • Mofi  · 技术社区  · 7 年前

    输入数据文件是嵌入式设备ADC值的捕获输出,以ASCII格式以八个十六进制值的数据包发送,并通过RS-232将回车加换行发送到PC,然后在PC上简单地捕获到文件中。输入数据文件中的一行类似于:

    000A002D0044008B0125018C01F40237
    

    此行的CSV文件为:

    10,45,68,139,293,396,500,567
    

    批处理文件工作正常,但完成转换需要几分钟,这让我感到震惊。我希望Windows命令处理器在这个任务中需要几秒钟,而C或C++中的控制台应用程序可以在几毫秒内完成。但对于小于512 KiB的数据文件,执行时间为几分钟,这绝对不是我所期望的。

    因此,我进一步研究了这个问题,使用四种不同的方法创建一个批处理文件,从一个具有十六进制值的数据文件创建一个具有十进制值的CSV文件。

    下面是测试这四种方法的完整批处理文件以及我的测试结果。

    由于调用子例程而导致的循环导致 cmd.exe 这需要花费大量的时间来执行数千次的子程序调用。

    但我真的不明白为什么第一种方法使用 后藤 对于 使用几乎相同的两个命令行进行循环。

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    set "DelDataFile="
    set "DataFile=%TEMP%\HexValues.dat"
    if not exist "%DataFile%" set "DelDataFile=1" & echo 000A002D0044008B0125018C01F40237>"%DataFile%"
    
    for /F "usebackq delims=" %%I in ("%DataFile%") do call :ConvertLine "%%I"
    
    if defined DelDataFile del "%DataFile%"
    endlocal
    goto :EOF
    
    :ConvertLine
    set "DataLine=%~1"
    set "AllValues="
    set "StartColumn=0"
    :NextValue
    set /A Value=0x!DataLine:~%StartColumn%,4!
    set "AllValues=%AllValues%,%Value%"
    set /A StartColumn+=4
    if not %StartColumn% == 32 goto NextValue
    echo %AllValues:~1%
    goto :EOF
    

    方法2的批处理文件代码:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    set "DelDataFile="
    set "DataFile=%TEMP%\HexValues.dat"
    if not exist "%DataFile%" set "DelDataFile=1" & echo 000A002D0044008B0125018C01F40237>"%DataFile%"
    
    for /F "usebackq delims=" %%I in ("%DataFile%") do call :LineConvert "%%I"
    
    if defined DelDataFile del "%DataFile%"
    endlocal
    goto :EOF
    
    :LineConvert
    set "DataLine=%~1"
    set "AllValues="
    for /L %%J in (0,4,28) do (
        set /A Value=0x!DataLine:~%%J,4!
        set "AllValues=!AllValues!,!Value!"
    )
    echo !AllValues:~1!
    goto :EOF
    

    问题是:

    是什么原因导致执行速度慢得多 方法1使用的循环与 对于 方法2使用的环路,为什么方法1依赖于PC的电源类型?


    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    cls
    set "TestRuns=5"
    set "DelDataFile="
    set "DataFile=%TEMP%\HexValues.dat"
    if exist "%DataFile%" goto InitMethod1
    
    set "DelDataFile=1"
    echo Creating data file which takes some seconds, please wait ...
    setlocal
    set "HexDigits=0123456789ABCDEF"
    set "DataLine="
    (for /L %%I in (0,1,32767) do (
        set /A "Digit1=(%%I >> 12) %% 16"
        set /A "Digit2=(%%I >> 8) %% 16"
        set /A "Digit3=(%%I >> 4) %% 16"
        set /A "Digit4=%%I %% 16"
        set "HexValue="
        for %%J in (!Digit1! !Digit2! !Digit3! !Digit4!) do set "HexValue=!HexValue!!HexDigits:~%%J,1!"
        set "DataLine=!DataLine!!HexValue!"
        set /A "ValuesPerLine=%%I %% 8"
        if !ValuesPerLine! == 7 (
            echo !DataLine!
            set "DataLine="
        )
    ))>"%DataFile%"
    endlocal
    echo/
    
    
    :InitMethod1
    call :MethodInit 1
    :RunMethod1
    set /A TestRun+=1
    set "CSV_File=%TEMP%\Values%Method%_%TestRun%.csv"
    del "%CSV_File%" 2>nul
    call :GetTime StartTime
    
    for /F "usebackq delims=" %%I in ("%DataFile%") do call :ConvertLine "%%I"
    
    call :OutputTime
    if %TestRun% LSS %TestRuns% goto RunMethod1
    call :MethodResults
    goto InitMethod2
    
    :ConvertLine
    set "DataLine=%~1"
    set "AllValues="
    set "StartColumn=0"
    :NextValue
    set /A Value=0x!DataLine:~%StartColumn%,4!
    set "AllValues=%AllValues%,%Value%"
    set /A StartColumn+=4
    if not %StartColumn% == 32 goto NextValue
    >>"%CSV_File%" echo %AllValues:~1%
    goto :EOF
    
    
    :InitMethod2
    call :MethodInit 2
    :RunMethod2
    set /A TestRun+=1
    set "CSV_File=%TEMP%\Values%Method%_%TestRun%.csv"
    del "%CSV_File%" 2>nul
    call :GetTime StartTime
    
    for /F "usebackq delims=" %%I in ("%DataFile%") do call :LineConvert "%%I"
    
    call :OutputTime
    if %TestRun% LSS %TestRuns% goto RunMethod2
    call :MethodResults
    goto InitMethod3
    
    :LineConvert
    set "DataLine=%~1"
    set "AllValues="
    for /L %%J in (0,4,28) do (
        set /A Value=0x!DataLine:~%%J,4!
        set "AllValues=!AllValues!,!Value!"
    )
    echo !AllValues:~1!>>"%CSV_File%"
    goto :EOF
    
    
    :InitMethod3
    call :MethodInit 3
    :RunMethod3
    set /A TestRun+=1
    set "CSV_File=%TEMP%\Values%Method%_%TestRun%.csv"
    del "%CSV_File%" 2>nul
    call :GetTime StartTime
    
    for /F "usebackq delims=" %%I in ("%DataFile%") do (
        set "DataLine=%%I"
        set "AllValues="
        for /L %%J in (0,4,28) do (
            set /A Value=0x!DataLine:~%%J,4!
            set "AllValues=!AllValues!,!Value!"
        )
        echo !AllValues:~1!>>"%CSV_File%"
    )
    
    call :OutputTime
    if %TestRun% LSS %TestRuns% goto RunMethod3
    call :MethodResults
    goto InitMethod4
    
    
    :InitMethod4
    call :MethodInit 4
    :RunMethod4
    set /A TestRun+=1
    set "CSV_File=%TEMP%\Values%Method%_%TestRun%.csv"
    del "%CSV_File%" 2>nul
    call :GetTime StartTime
    
    (for /F "usebackq delims=" %%I in ("%DataFile%") do (
        set "DataLine=%%I"
        set "AllValues="
        for /L %%J in (0,4,28) do (
            set /A Value=0x!DataLine:~%%J,4!
            set "AllValues=!AllValues!,!Value!"
        )
        echo !AllValues:~1!
    ))>>"%CSV_File%"
    
    call :OutputTime
    if %TestRun% LSS %TestRuns% goto RunMethod4
    call :MethodResults
    goto EndBatch
    
    
    :GetTime
    for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "%1=%%I"
    goto :EOF
    
    :MethodInit
    set "Method=%1"
    echo Test runs with method %Method%
    echo -----------------------
    echo/
    set "TestRun=0"
    set "TotalTime=0"
    goto :EOF
    
    :MethodResults
    set /A AverageTime=TotalTime / TestRun
    echo Method %Method% total time: %TotalTime% seconds
    echo Method %Method% average time: %AverageTime% seconds
    echo/
    goto :EOF
    
    :OutputTime
    call :GetTime EndTime
    set /A StartTime=(1%StartTime:~8,2% - 100) * 3600 + (1%StartTime:~10,2% - 100) * 60 + 1%StartTime:~12,2% - 100
    set /A EndTime=(1%EndTime:~8,2% - 100) * 3600 + (1%EndTime:~10,2% - 100) * 60 + 1%EndTime:~12,2% - 100
    set /A DiffTime=EndTime - StartTime
    set /A TotalTime+=DiffTime
    echo Method %Method% run %TestRun% time: %DiffTime% seconds
    goto :EOF
    
    
    :EndBatch
    if defined DelDataFile del "%DataFile%"
    del /Q "%TEMP%\Values?_*.csv"
    endlocal
    

    它首先在文件夹中为已经需要几秒钟的临时文件创建具有递增十六进制值的数据文件。请注释此批处理文件的倒数第二个命令行,以便在多次运行此批处理文件或对此文件感兴趣时保留该文件。

    .

    最后,它会删除文件夹中创建的所有CSV文件,这些临时文件都具有相同的内容。请评论最后一个命令行,以保持这些CSV文件对这些文件感兴趣。

    以下是第一次在笔记本电脑上运行的结果,该笔记本电脑采用2.26 GHz的Intel Core Duo P8400和2 GiB RAM,硬盘转速为7200 rpm,运行Windows XP x86并插入电源:

    Test runs with method 1
    -----------------------
    
    Method 1 run 1 time: 51 seconds
    Method 1 run 2 time: 51 seconds
    Method 1 run 3 time: 51 seconds
    Method 1 run 4 time: 52 seconds
    Method 1 run 5 time: 51 seconds
    Method 1 total time: 256 seconds
    Method 1 average time: 51 seconds
    
    Test runs with method 2
    -----------------------
    
    Method 2 run 1 time: 9 seconds
    Method 2 run 2 time: 9 seconds
    Method 2 run 3 time: 9 seconds
    Method 2 run 4 time: 8 seconds
    Method 2 run 5 time: 9 seconds
    Method 2 total time: 44 seconds
    Method 2 average time: 9 seconds
    
    Test runs with method 3
    -----------------------
    
    Method 3 run 1 time: 3 seconds
    Method 3 run 2 time: 3 seconds
    Method 3 run 3 time: 4 seconds
    Method 3 run 4 time: 3 seconds
    Method 3 run 5 time: 3 seconds
    Method 3 total time: 16 seconds
    Method 3 average time: 3 seconds
    
    Test runs with method 4
    -----------------------
    
    Method 4 run 1 time: 3 seconds
    Method 4 run 2 time: 2 seconds
    Method 4 run 3 time: 2 seconds
    Method 4 run 4 time: 2 seconds
    Method 4 run 5 time: 2 seconds
    Method 4 total time: 11 seconds
    Method 4 average time: 2 seconds
    

    方法2比方法1快5.67倍。方法3和方法4甚至比方法2快,但这是我所期望的。方法3和4所需的2秒和3秒大部分来自 WMIC

    Test runs with method 1
    -----------------------
    
    Method 1 run 1 time: 63 seconds
    Method 1 run 2 time: 61 seconds
    Method 1 run 3 time: 61 seconds
    Method 1 run 4 time: 61 seconds
    Method 1 run 5 time: 61 seconds
    Method 1 total time: 307 seconds
    Method 1 average time: 61 seconds
    
    Test runs with method 2
    -----------------------
    
    Method 2 run 1 time: 11 seconds
    Method 2 run 2 time: 10 seconds
    Method 2 run 3 time: 10 seconds
    Method 2 run 4 time: 10 seconds
    Method 2 run 5 time: 10 seconds
    Method 2 total time: 51 seconds
    Method 2 average time: 10 seconds
    
    Test runs with method 3
    -----------------------
    
    Method 3 run 1 time: 3 seconds
    Method 3 run 2 time: 4 seconds
    Method 3 run 3 time: 3 seconds
    Method 3 run 4 time: 4 seconds
    Method 3 run 5 time: 3 seconds
    Method 3 total time: 17 seconds
    Method 3 average time: 3 seconds
    
    Test runs with method 4
    -----------------------
    
    Method 4 run 1 time: 2 seconds
    Method 4 run 2 time: 2 seconds
    Method 4 run 3 time: 2 seconds
    Method 4 run 4 time: 2 seconds
    Method 4 run 5 time: 2 seconds
    Method 4 total time: 10 seconds
    Method 4 average time: 2 seconds
    

    可以看出,对于方法2到4,处理时间只增加了一点点。但方法1的处理时间增加了10秒,因此该解决方案现在比方法2慢6.10倍。我不知道为什么方法1的处理时间取决于电源类型。

    以下是首次在笔记本电脑上运行的结果,该笔记本电脑采用2.80 GHz的Intel Core Duo T9600和4 GiB RAM,SSD运行Windows 7 x64,并插入电源:

    Test runs with method 1
    -----------------------
    
    Method 1 run 1 time: 91 seconds
    Method 1 run 2 time: 88 seconds
    Method 1 run 3 time: 77 seconds
    Method 1 run 4 time: 77 seconds
    Method 1 run 5 time: 78 seconds
    Method 1 total time: 411 seconds
    Method 1 average time: 82 seconds
    
    Test runs with method 2
    -----------------------
    
    Method 2 run 1 time: 11 seconds
    Method 2 run 2 time: 16 seconds
    Method 2 run 3 time: 16 seconds
    Method 2 run 4 time: 14 seconds
    Method 2 run 5 time: 16 seconds
    Method 2 total time: 73 seconds
    Method 2 average time: 14 seconds
    
    Test runs with method 3
    -----------------------
    
    Method 3 run 1 time: 6 seconds
    Method 3 run 2 time: 4 seconds
    Method 3 run 3 time: 4 seconds
    Method 3 run 4 time: 4 seconds
    Method 3 run 5 time: 6 seconds
    Method 3 total time: 24 seconds
    Method 3 average time: 4 seconds
    
    Test runs with method 4
    -----------------------
    
    Method 4 run 1 time: 4 seconds
    Method 4 run 2 time: 3 seconds
    Method 4 run 3 time: 5 seconds
    Method 4 run 4 time: 4 seconds
    Method 4 run 5 time: 4 seconds
    Method 4 total time: 20 seconds
    Method 4 average time: 4 seconds
    

    对于 而不是 环

    Test runs with method 1
    -----------------------
    
    Method 1 run 1 time: 97 seconds
    Method 1 run 2 time: 91 seconds
    Method 1 run 3 time: 90 seconds
    Method 1 run 4 time: 81 seconds
    Method 1 run 5 time: 77 seconds
    Method 1 total time: 436 seconds
    Method 1 average time: 87 seconds
    
    Test runs with method 2
    -----------------------
    
    Method 2 run 1 time: 12 seconds
    Method 2 run 2 time: 16 seconds
    Method 2 run 3 time: 17 seconds
    Method 2 run 4 time: 16 seconds
    Method 2 run 5 time: 13 seconds
    Method 2 total time: 74 seconds
    Method 2 average time: 14 seconds
    
    Test runs with method 3
    -----------------------
    
    Method 3 run 1 time: 6 seconds
    Method 3 run 2 time: 6 seconds
    Method 3 run 3 time: 5 seconds
    Method 3 run 4 time: 5 seconds
    Method 3 run 5 time: 5 seconds
    Method 3 total time: 27 seconds
    Method 3 average time: 5 seconds
    
    Test runs with method 4
    -----------------------
    
    Method 4 run 1 time: 4 seconds
    Method 4 run 2 time: 4 seconds
    Method 4 run 3 time: 5 seconds
    Method 4 run 4 time: 4 seconds
    Method 4 run 5 time: 4 seconds
    Method 4 total time: 21 seconds
    Method 4 average time: 4 seconds
    

    与插入电源的第三次运行相比,方法3至4的执行时间也没有太大差异。但是方法1的执行时间增加了大约5秒,因此方法1比方法2慢6.21倍。

    我真的很想知道为什么方法1比方法2慢得多,而且还要依赖于电源的种类。

    由于Windows文件缓存,硬盘活动指示灯在所有测试运行中很少像我预期的那样闪烁。

    5 回复  |  直到 7 年前
        1
  •  4
  •   mnistic    7 年前
        2
  •  4
  •   Matt Timmermans    7 年前

    如果我没有记错的话,批处理文件中的GOTO LABEL命令实际上会扫描文本的其余部分以查找标签,如果找不到标签,则会在顶部重新启动。

    因此,如果您关心性能,那么您应该尽量避免这些构造。或者,更好的是,不要在批处理文件中进行这种工作。

        3
  •  3
  •   Stephan    7 年前

    这是因为路的缘故 goto 作品与编译编程语言不同,其中 后藤 在编译过程中被翻译成固定地址,批处理必须在文件中搜索每个文件的标签 后藤 .

    后藤 行,如果找不到标签,则从文件的开头继续搜索。

        4
  •  1
  •   jeb    7 年前

    如前所述, GOTO 和 CALL 从当前文件位置到文件结尾搜索与标签匹配的下一个标签,然后从文件开头搜索到当前文件位置。
    这种行为有一些有用的效果,因为您不必担心函数中的不同标签名称。

    :myFunc1
    <some code>
    goto :someLabel  -- this goto's to the next :someLabel  
    
    :someLabel
    
    :myFunc2
    <some code>
    goto :someLabel  -- this goto's to the next :someLabel  
    
    :someLabel  
    


    相关话题
    Rules for label names vs GOTO and CALL
    CALL me, or better avoid call

        5
  •  1
  •   Mofi    7 年前

    谢谢你的回答。看起来你很好。

    原因是正在搜索引用的标签 首先在批处理文件中向下,然后从顶部到文件底部都找不到它。

    我验证了使用第一个批处理文件时,文件大小为941字节,行数如下:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "StartTime=%%I"
    for /F "usebackq delims=" %%I in ("%TEMP%\HexValues.dat") do call :ConvertLine "%%I"
    for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "EndTime=%%I"
    set /A StartTime=(1%StartTime:~8,2% - 100) * 3600 + (1%StartTime:~10,2% - 100) * 60 + 1%StartTime:~12,2% - 100
    set /A EndTime=(1%EndTime:~8,2% - 100) * 3600 + (1%EndTime:~10,2% - 100) * 60 + 1%EndTime:~12,2% - 100
    set /A DiffTime=EndTime - StartTime
    echo Time: %DiffTime% seconds
    endlocal
    goto :EOF
    
    :ConvertLine
    set "DataLine=%~1"
    set "AllValues="
    set "StartColumn=0"
    :NextValue
    set /A Value=0x!DataLine:~%StartColumn%,4!
    set "AllValues=%AllValues%,%Value%"
    set /A StartColumn+=4
    if not %StartColumn% == 32 goto NextValue
    goto :EOF
    

    花了 34 51 Windows XP笔记本电脑上的秒数。

    goto :EOF 和 :ConvertLine 包含250行且所有行都具有相同字符串的块:

    rem comment line of no interest
    

    此批处理文件需要9193字节 64 秒完成完全相同的任务。

    主要地 因为同样的原因。

    但我仍然没有找到为什么第二批处理文件需要9193字节 72 秒而不是 笔记本电脑上的秒数使用电池而不是插入电源。批处理文件和数据文件加载到缓存中。运行批处理文件时没有输出。我在电源选项中配置了在电池上运行时使用最高性能。在批处理文件中扫描标签在电池上运行时明显比在插入电源上运行时慢,尽管在批处理文件执行期间并没有真正访问硬盘,只有CPU核心、CPU缓存和RAM。

    TIME 环境变量,而不是使用 WMIC %TIME% 在我的电脑上扩展为德语时间格式 HH::MM:SS.ms .

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    set "StartTime=%TIME%"
    for /F "usebackq delims=" %%I in ("%TEMP%\HexValues.dat") do call :ConvertLine "%%I"
    set "EndTime=%TIME%"
    set /A StartTime=(1%StartTime:~0,2% - 100) * 3600 + (1%StartTime:~3,2% - 100) * 60 + 1%StartTime:~6,2% - 100
    set /A EndTime=(1%EndTime:~0,2% - 100) * 3600 + (1%EndTime:~3,2% - 100) * 60 + 1%EndTime:~6,2% - 100
    set /A DiffTime=EndTime - StartTime
    echo Time: %DiffTime%
    endlocal
    goto :EOF
    
    :ConvertLine
    set "DataLine=%~1"
    set "AllValues="
    set "StartColumn=0"
    :NextValue
    set /A Value=0x!DataLine:~%StartColumn%,4!
    set "AllValues=%AllValues%,%Value%"
    set /A StartColumn+=4
    if not %StartColumn% == 32 goto NextValue
    goto :EOF
    

    此批处理文件在中完成 30 在Windows XP x86(硬盘驱动器为ST980411ASG,转速为7200 rpm)上插入电源后运行秒。下一个在电池上运行的批处理文件 37

    花了 72 使用Windows 7 x64和三星SSD 850 EVO(固态磁盘)并插入电源和 77 在电池上运行的秒数。我刚刚在两次测试之间切断了电源,没有其他变化。没有连接到任何网络,每个硬件交换机关闭WLAN,BIOS中禁用蓝牙,执行期间禁用防病毒应用程序(Windows 7x 64上的Windows Defender除外)。

    我用Windows7x64在PC上一次又一次地运行这个批处理文件,最后在执行过程中经常打开风扇,执行时间随着时间的推移变得恒定 秒独立于电源是否插入。

    为了进行比较,我还执行了这个批处理文件:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    set "StartTime=%TIME%"
    for /F "usebackq delims=" %%I in ("%TEMP%\HexValues.dat") do (
        set "DataLine=%%I"
        set "AllValues="
        for /L %%J in (0,4,28) do (
            set /A Value=0x!DataLine:~%%J,4!
            set "AllValues=!AllValues!,!Value!"
        )
    )
    set "EndTime=%TIME%"
    set /A StartTime=(1%StartTime:~0,2% - 100) * 3600 + (1%StartTime:~3,2% - 100) * 60 + 1%StartTime:~6,2% - 100
    set /A EndTime=(1%EndTime:~0,2% - 100) * 3600 + (1%EndTime:~3,2% - 100) * 60 + 1%EndTime:~6,2% - 100
    set /A DiffTime=EndTime - StartTime
    echo Time: %DiffTime%
    endlocal
    

    在运行Windows XP的电脑上,需要1到2秒的时间才能完成,因此,在插入电源的情况下,完成时间通常为1秒,而在使用电池的情况下,完成时间通常为2秒。我还需要考虑毫秒,以便更精确地处理这个快速完成的解决方案。在PC Windows 7 x64上的执行时间在4到5秒之间,与其他Windows XP笔记本电脑一样,插入电源的时间也有缩短的趋势。

    但我可以用你的眼睛看 Process Monitor 后藤 使用最优化的版本,在几乎没有批处理文件访问的情况下进行循环 对于 环

    及 cmd.exe 真正地一行一行地读取批处理文件 后藤 方法,因为它也可以看到与过程监控对大量的 ReadFile 访问量与日俱增 Offset 偏移量与批处理文件中每行开头的偏移量相同。Process Monitor记录文件系统访问时,由于记录的事件超过两百万个,显示的事件超过500000个,因此执行时间显著增加。

    对于 循环那个 命令提示符 读到最后一行 循环,然后读取一次 HexValues.dat 只有一个 access,需要5秒钟(在Windows 7 x64上)完成从十六进制到十进制的转换,而无需任何文件系统访问,然后读取批处理文件的其余行以完成其执行。Process Monitor只记录大约50000个事件,显示的事件不到100个。

    后藤

    结论:

    这个 后藤 方法1的求解速度比所有其他方法慢得多,因为 goto NextValue 根据 Aacini

    1. 打开批处理文件以读取和查询有关文件的标准信息,以检查自上次访问以来批处理文件是否已更改。在下面的其他步骤中,不会查询标准信息。
    2. 从批处理文件中一行接一行地读取,并处理每一行,以查找具有 :NextValue 没有成功结束文件。
    3. 从批处理文件的最上面一行接一行地读取,然后处理每一行以查找具有 :下一个值 .
    4. :下一个值
    5. set /A Value=0x!DataLine:~%StartColumn%,4! .
    6. 处理读取命令行。
    7. 读下一行 set "AllValues=%AllValues%,%Value%" 从批处理文件。
    8. 处理读取命令行。
    9. 再次打开批处理文件。
    10. 读下一行 set /A StartColumn+=4
    11. 关闭批处理文件。
    12. 处理读取命令行。
    13. if not %StartColumn% == 32 goto NextValue 从批处理文件。
    14. 关闭批处理文件。
    15. 处理读取命令行。
    16. 如果条件为真,则继续执行第一步,即。 StartColumn 不是 32 .

    所有这些批处理文件 即使不访问存储介质,操作也需要几毫秒,但是 很可能 (我的假设)在访问主板上的DRAM时,由于整个批处理文件内容没有加载到CPU的内部缓存中,所以在主板上加载了文件。

    因此,使用 对于 通过方法2在子例程中循环批处理文件访问操作的数量已经大大减少,因为在处理从中读取的当前行中的十六进制值时,不需要执行21个步骤(具有更多文件访问操作)逐行读取批处理文件,也不需要显式列出所有单个步骤 .

    所有的线都在里面 HexValues.dat 可以由 命令提示符 在一次完成整个转换时不访问批处理文件 按照方法3和4进行循环。最后,通过将CSV的所有行输出到,可以保存更多的文件系统访问 STDOUT (内存中的缓冲区)并将其写入CSV文件一次,如方法4所做,与方法3相比,再次减少此值转换任务所需的总时间。

    应该避免在命令行中使用 goto LABEL 或 call :LABEL 具有 LABEL 在一个更大的批处理文件中,位于当前行的上方或下方的许多行,在一个循环中进行数百或数千次迭代。一个复杂的问题不容易理解 对于 后藤 或 呼叫 . 或者换句话说,只使用一个 对于 经常在循环中做一些事情。

    推荐文章