Batch file 有没有像批处理代码优化器这样的东西?

Batch file 有没有像批处理代码优化器这样的东西?,batch-file,optimization,filesize,Batch File,Optimization,Filesize,所以你知道,当人们写代码时,他们写得很整洁,外观最好,也最容易理解。但是否有一个用于批处理的优化器?有人能做一个吗 示例- 它接受现有变量并用尽可能短的变量替换它们 set whatever=whatever echo question set /p answer=: if %answer%=%whatever% whatever 把它变成 set a=whatever echo question set /p b=: if %b%=%a% whatever 因此,它基本上缩短了变量、标志(

所以你知道,当人们写代码时,他们写得很整洁,外观最好,也最容易理解。但是否有一个用于批处理的优化器?有人能做一个吗

示例- 它接受现有变量并用尽可能短的变量替换它们

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)并做了其他我无法做的事情来基本上优化所有内容。

批处理程序中有某些结构会降低执行速度。对这一点有重大影响的唯一构造是通过
GOTO
而不是任何类型的
for
命令来组装一个循环。如果使用FOR命令重写具有多个转到的大型程序,则可以节省大量时间。影响这一点的另一个方面是一个程序的命令/行数,也就是说,与另一个具有较少行数的程序相比,获得相同结果的程序将运行得更快。用较少的命令实现相同功能的方法是充分利用批处理文件功能

例如,此代码:

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
for %%e in (1 2 3) do if %errorlevel% equ %%e goto label-%%e
command-that-return-errorlevel
goto label-%errorlevel%
此代码:

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
。。。运行速度比这个慢:

set /A b=a+8, c=b*2, d=c+e
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%
。。。前一个运行速度比这个慢:

set /A b=a+8, c=b*2, d=c+e
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%
缩短变量名对执行速度的影响很小


这样,最好的选择是从一开始就使用这些技术编写批处理文件。开发一个程序来读取批处理文件并执行以前的更改是不容易的,也就是说,用
FOR
替换
GOTO
,并用更少的行“压缩”几行。

下面的程序只是为了好玩

@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"
@echo关闭
setlocal EnableDelayedExpansion
rem获取当前变量名的列表
(对于/F“delims==”%%v in('set')do(
回声%%v
))>varnames.txt
rem调用批处理文件,以便创建其变量
调用“%~1”
rem使用新变量名创建数组
设置“\u numVars=”
设置“_nextVar=”
“%~1.新的”

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

如果你克服了将遇到的问题,它会将编写良好的批处理文件变成难以阅读的代码,毫无益处。如果你减少批处理文件大小甚至增加了2 KB,现在硬盘上的群集大小通常超过8 KB,而且这样的批处理文件在任何合理的基准测试下都不会运行得更快。这将是一个有趣(可能令人沮丧)的练习:
@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"