&&关于代码运行的效率,本人以前也在各种回贴中多次提及。写出来的代码效率不高
这是新手们经常出现的问题,这是正常的,高手们也都是从这个阶段走过来的。新手们
刚开始自己写代码时应重在于解决问题上,只要代码能够解决问题,这就是成功,关于
代码的简洁和效率问题,只有在不断的学习和练习中去慢慢解决它。当然,新手们在编
写代码时还应多听听老手们的意见。下面本人就结合个人的经验来谈谈如何提高代码运
行时的效率:
1、call语式是批处理中经常使用的语式,在代码中合理地运用call能大大减少代码,
但,就如随风兄所说的一样,如果在代码中调用call的次数过多的话,代码的效率就会明
显降低,同时还有call的变量延迟功能在反复赋值的情况下也会降低代码效率,下面就以
两段代码来说明下这个问题(call语式的例子随风兄已给出,在这里就不再举例了):- @echo off&setlocal enabledelayedexpansion
- set "t=%time%"
- for /l %%i in (1,1,10000) do (
- set "str=%%i"
- echo !str!
- )
- echo 开始时间%t%
- echo 结束时间%time%
- pause>nul
复制代码
- @echo off
- set "t=%time%"
- for /l %%i in (1,1,10000) do (
- set "str=%%i"
- call,echo %%str%%
- )
- echo 开始时间%t%
- echo 结束时间%time%
- pause>nul
复制代码 分别运行这两段代码你会发现第二段代码运行的时间远远长于第一段代码,这就是
因为反复使用了10000次call延迟的原因。
2、新手们在刚刚接触for循环特别是多个for循环的嵌套时也经常会出现效率上的大
问题,而这个效率问题就是总循环次数是+还是*的问题,可能这样说大家不是很明白,
下面一样结合代码来说明吧:
有a.txt、b.txt,两文本行数相同(假设为均有100行)现在要求通过批处理将两文本
相同行数的内容合并输出并在中间以一个#来连接- @echo off&setlocal enabledelayedexpansion
- set "t=%time%"
- for /f "delims=" %%a in (a.txt) do ([
- set /a n+=1,m=0
- for /f "delims=" %%i in (b.txt) do (
- set /a m+=1
- if !n! equ !m! echo %%a#%%i
- )
- )
- echo 开始时间%t%
- echo 结束时间%time%
- pause>nul
复制代码
- @echo off
- set "t=%time%"&set "n=-1"
- :begin
- set /a n+=1
- if %n% equ 0 (
- set "sk="
- ) else (
- set "sk=skip=%n%"
- )
- for /f "%sk% delims=" %%i in (a.txt) do set /p=%%i#<NUL&GOTO next
- :next
- for /f "%sk% delims=" %%i in (b.txt) do set /p=%%i<NUL&ECHO.&GOTO begin
- echo 开始时间%t%
- echo 结束时间%time%
- pause>nul
复制代码
大家可以看出第二段代码比起第一段代码要复杂,那么运行效率呢,实际上第二段
代码的效率是远高于第一段代码的,为什么呢?我们就来分析一下吧:第一段代码先是
从a.txt中读取第一行内容然后将n值加1并将m值归0,然后进行b.txt开始逐行读取并将每
次将m值加1如遇到n值和m值相同时就输出a.txt中的第一行和b.txt中的这一行(实际也
就是b.txt中的第一行),然后再读取a.txt中的第二行再重复上述比对和输出,如此当整个
循环运行完成,第二个for循环就足足整个比对了b.txt100次,也就是比对了10000行的内
容;而第二段代码是先从a.txt中读取第一行并输出然后跳到b.txt读取和输出第一行内容
再返回begin标签,再用skip来忽略a.txt的第一行读取输出第二行后又跳到b.txt同样用skip
忽略掉b.txt的第一行读取和输出b.txt的第二行再次返回begin标签,如此一直到所有的内
容被输出,所以其总共的读取次数是200,这也是最少的比对次数,100+100和100*100
相信大家都知道谁快谁慢了吧。
3、还有一个不但是新手同样老手也会常出现的效率问题,那就是在设计代码方案时
存在的问题,本来在一个代码不需要进行比对和返回而设计了比对和返回,以代码示之:
如随机生成9000个不同的0-10000内的数- @echo off
- set "t=%time%"
- :begin
- set /a a=%random%%%10000+1
- if not defined _%a% (
- set /p=%a% <NUL
- set /a n+=1&set "_%a%=a"
- ) else (
- goto begin
- )
- if %n% neq 9000 goto begin
- echo.&echo 开始时间%t%
- echo 结束时间%time%
- pause>nul
复制代码
- @echo off&setlocal enabledelayedexpansion
- set "t=%time%"
- for /l %%i in (0,1,10000) do set "_!random!!random!!random!!random!=%%i"
- for /f "tokens=2 delims==" %%i in ('set _') do (
- set /p=%%i <NUL
- set /a n+=1
- if !n! equ 9000 goto end
- )
- :end
- echo.&echo 开始时间%t%
- echo 结束时间%time%
- pause>nul
复制代码
第一段代码将会慢得让你的机器都不能忍受,就是因为其中不可计数的比对和返回
次数大大降低了运行的效率,当然在所取数和基数相差值较大的情况下这种方案还是可
以采用的。
好了,说了这么一大通无非就是请大家在设计和编写代码时多多考虑效率方面的问
题,如有解释得不透或有误的地方还望大家指出了。
[ 本帖最后由 batman 于 2008-10-7 16:21 编辑 ] |