[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[转贴] 浅谈提高批处理代码效率的编写习惯

一,慎用外部命令


1、能用内部命令就用尽量内部命令
  1. more 1.txt
复制代码
  1. type 1.txt
复制代码
rem 后者一定比前者快,因为甭管外部命令运行时效率多高,它们启动慢的缺陷就导致了不适宜大量使用,当然,碰到“专业对口”或者要处理大文件的情况,还是可以请外部命令出山的,不过一定切忌滥用。


2,尤其要避免在循环中频繁执行外部命令
  1. for %%a in (*.txt) do (
  2.     findstr test "%%a"&&echo 在 "%%a" 中找到关键词
  3. )
复制代码
  1. for /f "delims=" %%a in ('findstr /m test *.txt') do (
  2.     echo 在 "%%a" 中找到关键词
  3. )
复制代码
rem 实现同样的功能,前者的设计却是非常不合理的,在循环体重频繁调用外部命令将极大地影响脚本效率,也十分消耗系统资源。所以,非要用外部命令的话一定要尽量在外层循环中使用,以降低调用次数。


3,避免频繁从命令中获取输入
  1. for /f "delims=" %%a in ('type 1.txt') do echo %%a
复制代码
  1. for /f "delims=" %%a in (1.txt) do echo %%a
复制代码
rem 前者看似只是多执行了一个 type,for /f 从命令获取输入的本质是以 cmd /c 开启新的 cmd 进程来执行命令,for 命令再获取其输出作为输入,所以一旦直接从命令中获取输入,等于运行了一次 cmd /c,也就是外部命令。


4、好钢用在刀刃上
  1. for /f "delims=" in (大文件.txt) do set /a "n+=1"&echo !n!:%%a
复制代码
  1. findstr . 大文件.txt|findstr /n .*
复制代码
rem 碰到大文件时,与大量的内部命令相比,一两个外部命令的启动耗时将不足为道,这时用外部命令效率反而更高
2

评分人数

二,选择合理的循环方式


1、少用 call 和 goto
  1. :a
  2. set /a n+=1
  3. echo %n%
  4. if %n% lss 100 goto a
  5. pause
复制代码
  1. for /l %%a in (1 1 100) do echo %%a
  2. pause
复制代码
rem for 的效率远超 call 与 goto,所以尽量用 for 作为循环结构的主体,尤其要注意的是,%0 这种循环方式其实是执行 cmd /c,cmd 是外部命令,所以这也是很低效的


2、大循环中避免使用 goto
  1. for /l %%a in (1 1 1000000) do if %%a==1 goto next
  2. :next
  3. pause
复制代码
  1. for /l %%a in (1 1 1000000) do if %%a==1 call :next
  2. :next
  3. pause
复制代码
rem for 迭代无法打断,goto 必须等待所有迭代的预处理都执行完毕才能跳转,而 call 却是立刻跳转,不过执行完了还得回来,并且存在 call 的次数上限,所以用哪个应该视情况而定

TOP

三,合理使用临时文件


1,从命令获取大量输入时,尽量使用临时文件
  1. for /f "delims=" %%a in ('dir /s /b \') do echo %%a
复制代码
  1. dir /s /b \>tmp.txt
  2. for /f "delims=" %%a in (tmp.txt) do echo %%a
复制代码
rem 因为前者是把“临时文件”放在内存中的,过量的内存占用将明显影响 cmd 的执行效率,后者却不用担心这一点。


2,前后存在内部命令或者语块时慎用管道
  1. (for /l %%a in (1 1 1000) do echo %%a)|sort
复制代码
  1. (for /l %%a in (1 1 1000) do echo %%a)>tmp.txt
  2. sort tmp.txt
复制代码
rem 前者的管道符前后存在语块,将开启新的 cmd 进程来执行此处的 for /l,所以降低了效率,此时改用临时文件就快了许多

TOP

四,for 嵌套中,越稳定的循环应该越少参与递归


1,参数固定的 for 应位于最外层
  1. for /l %%a in (1 1 1000) do (
  2.     for /f "tokens=2" %%b in ("abc test 123") do echo %%a%%b
  3. )
复制代码
  1. for /f "tokens=2" %%a in ("abc test 123") do (
  2.     for /l %%b in (1 1 1000) do echo %%a%%b
  3. )
复制代码
rem 同样的代码仅仅是次序不同,实现同样的效果的用时却是后者更快,因为那句 for /f 的结果是恒定的,所以前者产生了 999 次多余的循环


2,越小的循环越靠外
  1. for /l %%a in (1 1 1000) do (
  2.     for /l %%b in (1 1 10) do title %%a%%b
  3. )
复制代码
  1. for /l %%a in (1 1 10) do (
  2.     for /l %%b in (1 1 1000) do title %%a%%b
  3. )
复制代码
rem 这两段中的 for 循环的参数同样都是“不稳定的”,但是后者就是比前者快上一筹


3,越核心的递归层,命令最好越少
  1. for /l %%a in (1 1 100) do (
  2.     for /l %%b in (1 1 100) do (
  3.         set /a n=%%b*2
  4.         echo %%a,!n!
  5.     )
  6. )
复制代码
  1. for /l %%a in (1 1 100) do (
  2.     set /a n=%%a*2
  3.     for /l %%b in (1 1 100) do echo !n!,%%b
  4. )
复制代码
rem 前后代码的输出量是相同的,但是因为后者内层的循环中命令很少,所以效率就高了很多

TOP

五,操作尽量少


1、命令能合并就合并
  1. set m=%m: =%
  2. set m=@%m%@
复制代码

  1. set m=@%m: =%@
复制代码

rem 命令少一条是一条,这对效率的提升也是很直观的


2、充分利用命令的特性
  1. (for %%a in (*.txt) do type %%a)>out.txt
复制代码

  1. type *.txt>out.txt
复制代码

rem 很多命令本身就具有批量操作的能力,或者它们的某些特性可以被另类地利用,所以平时应该多挖掘命令的潜力


3、重定向的次数尽量少
  1. for /l %%a in (1 1 1000) do echo>>1.txt %%a
复制代码

  1. (for /l %%a in (1 1 1000) do echo %%a)>>1.txt
复制代码

rem 重定向也是消耗时间的,所以能一次性搞定最好

4、变量尽量少
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1* delims=:" %%a in ('findstr /n .* 大文件.txt') do (
  3. set n=%%a
  4. set @!n!=%%b
  5. )
  6. (for /l %%a in (!n! -1 1) do echo;!@%%a!)>倒文.txt
  7. pause
复制代码

  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "tokens=1* delims=:" %%a in ('findstr /n .* 大文件.txt') do (
  3. set n=0000%%a
  4. echo !n:~-5! %%b
  5. ))>tmp.txt
  6. (for /f "tokens=1*" %%a in ('sort /r tmp.txt') do echo;%%b)>倒文.txt
  7. pause
复制代码

rem 以上两条均为从文件中倒序输出文本的代码,但是后者在处理大文件时要快上很多,因为 cmd 是以变量表的方式有序保存变量的,所以变量多时,存取变量有明显的延时,换句话说,变量越多,运行越慢。


转自:http://tieba.baidu.com/p/1187281687
2

评分人数

TOP

返回列表