【问题标题】:Is there such a thing as a batch code optimizer?是否有批处理代码优化器之类的东西?
【发布时间】:2013-10-22 03:02:22
【问题描述】:

所以你知道,当人们编写代码时,他们会做的很简洁、最好看并且最容易理解。但是有批处理优化器吗?有人可以做一个吗?

示例- 它采用现有变量并用最短的变体替换它们

set whatever=whatever
echo question
set /p answer=:
if %answer%=%whatever% whatever

并把它变成

set a=whatever
echo question
set /p b=:
if %b%=%a% whatever

所以它基本上缩短了变量、标志(或标签或任何类似的东西:top)并做其他我无法做的事情来优化一切。

【问题讨论】:

  • 如果你克服了你会遇到的问题,它将把一个写得很好的批处理文件变成一段难以阅读的代码,而没有任何好处。如果您将批处理文件的大小减少 2 KB,那么如今硬盘驱动器上的集群大小通常超过 8 KB,此外,任何合理的基准测试都不会更快地运行此类批处理文件。这将是一个有趣的(也可能是令人沮丧的)练习。 :)

标签: batch-file optimization filesize


【解决方案1】:

批处理程序中的某些结构会减慢执行速度。对这一点有重大影响的唯一构造是通过GOTO 而不是任何类型的FOR 命令组装一个循环。如果使用FOR 命令重写具有许多GOTO 的大型程序,预计会节省大量时间。影响这一点的另一个方面是程序具有的命令/行数,也就是说,与另一个程序获得相同结果但行数更少的程序将运行得更快。用更少的命令来完成同样的事情的方法是充分利用批处理文件的能力。

例如这段代码:

set /A b=a+8
set /A c=b*2
set /A d=c+e

...跑得比这个慢:

set /A b=a+8, c=b*2, d=c+e

这段代码:

command-that-return-errorlevel
if %errorlevel% equ 1 goto label-1
if %errorlevel% equ 2 goto label-2
if %errorlevel% equ 3 goto label-3

...跑得比这个慢:

command-that-return-errorlevel
for %%e in (1 2 3) do if %errorlevel% equ %%e goto label-%%e

...和前一个运行速度比这个慢:

command-that-return-errorlevel
goto label-%errorlevel%

缩短变量名对执行速度影响很小。

这样,最好的选择是从一开始就使用这些技术编写批处理文件。开发一个读取 Batch 文件并执行先前更改的程序没有简单的方法,即将GOTO 替换为FOR 并在更少的行中“压缩”几行。

【讨论】:

    【解决方案2】:

    下面的程序只是为了好玩!

    @echo off
    setlocal EnableDelayedExpansion
    
    rem Get a list of current variable names
    (for /F "delims==" %%v in ('set') do (
       echo %%v
    )) > varnames.txt
    
    rem Call the Batch file, so it creates its variables
    call "%~1"
    
    rem Create an array with new variable names
    set "_numVars="
    set "_nextVar="
    < varnames.txt (for /F "delims==" %%v in ('set') do (
       if not defined _nextVar set /P _nextVar=
       if "%%v" neq "!_nextVar!" (
          set /A _numVars+=1
          set "var[!_numVars!]=%%v"
       ) else (
          set "_nextVar="
       )
    ))
    del varnames.txt
    
    rem Rename the variables in a new file
    setlocal DisableDelayedExpansion
    (for /F "delims=" %%a in ('findstr /N "^" "%~1"') do (
       set "line=%%a"
       setlocal EnableDelayedExpansion
       set "line=!line:*:=!"
       if defined line (
          for /L %%i in (1,1,%_numVars%) do (
             for /F "delims=" %%v in ("!var[%%i]!") do set "line=!line:%%v=v%%i!"
          )
       )
       echo(!line!
       endlocal
    )) > "%~1.new"
    

    该程序从参数中给出的批处理文件中获取所有变量,并将它们重命名为“v#”,并带有序号。要使用此程序,您必须先从批处理文件中删除任何setlocal 命令,然后再将其传递给此程序。当然,这个细节可能会导致几个陷阱:虽然被调用的程序已经启用了延迟扩展,但无法激活批处理文件可能需要的任何禁用/启用延迟扩展才能正确运行。此外,程序会更改批处理文件中与任何变量名相同的所有字符串,但即使可以修复这一点(这是一个很大的 IF,因为它需要模拟 cmd. exe 批处理文件解析器!)这个程序仍然没用:正如我在另一个答案中所说,重命名批处理文件中的变量对其性能影响很小。我只是为了好玩才写的!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多