[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
第一个for的if defined判断可以去掉,变量判断也是要时间的。
因为 . 号在任何系统变量的前面,加一个 . 可以免掉批处理在匹配变量时,对系统变量的扫描,可以加快速度。
其实最好是在前面加 # 号或 $  号,因为它们还要在 . 号的前面。

按楼主的数据,下面的代码应该可以提速3分钟左右。
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt) do set #%%a=i
  4. (for /f "delims=" %%a in (A.txt) do (if not defined #%%a (echo %%a)))>888.txt
  5. echo %tm% %time%
  6. pause
复制代码


2009.6.28
[更正]  “加.可以提速”的错语说法,如果使用的变量数量不是很大时,确实可以小提速,但是如果变量数量越大,就会让很多的.也占用了内存。变成得不尝失了。

我了解到:
批处理的变量在内存中的是这样连续存放的(即变量环境)

0 “变量名1”=“变量值1”0 “变量名2”=“变量值2”0 “变量名3”=“变量值3”0 。。。

并由[变量环境长度]保存所占内在的大小

当设置变量时,会先对整个变量环境进行扫描,如果已经有该变量名,则把该变量取出,其后面的变量内容前移,然后再把设置的变量及新值放在最后,再修改[变量环境长度]的值。如果环境中还没有该变量,则直接放在最后。

可以看出,每一次变量的设置及取值,都会对[变量环境]进行一次扫描,虽然内存的读取速度很快,但是随着[变量环境]的增大,需要扫描的范围也就越大,速度肯定会越慢。

所以增加的 . 会随着变量数量的增加,明显的使用[环境变量]“肥”了不少

看来,对于批处理效率来说,变量名是越短越高效的。

[ 本帖最后由 netbenton 于 2009-6-28 11:26 编辑 ]

TOP

回复 14楼 的帖子

你这个代码测试的时间是39分29秒
学海无涯

TOP

第一个for的if defined判断确实可以去掉,但考虑到楼主已经测试了很多代码而且耗时都不短,为了在同一起跑线,所以后面的代码都特意保留了第一个for 的 if defined
但现在看楼主的测试结果,说实话对楼主的测试环境很是怀疑。
似乎他的第一个代码效率是最高的。而从我们的理论上来说却应该是最低的~
技术问题请到论坛发帖求助!

TOP

不防把三个代码都编个号
代码一、
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  4. for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a>>888.txt
  5. echo %tm% %time%
  6. pause
复制代码
代码二、
  1. @echo off
  2. set tm=%time%
  3. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  4. (for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a)>888.txt
  5. echo %tm% %time%
  6. pause
复制代码
代码三、
  1. @echo off
  2. set tm=%time%
  3. echo. >nul 3>888.txt
  4. for /f "delims=" %%a in (B.txt)do if not defined .%%a set ".%%a=i"
  5. for /f "delims=" %%a in (A.txt)do if not defined .%%a echo %%a
  6. echo. >nul 4>con
  7. echo %tm% %time%
  8. pause
复制代码
三个代码,不知道最后结果888.txt有多少行?先假设是9楼 keen 推测的2万行吧。
第一个代码和第二个代码的区别是
第一个代码只有第一个for占用了内存,但开关 i/o 2万次。
第二个代码两个for都占用了内存,但开关 i/o 1次
但这两个代码的效率却差不多,说明什么?
难道说开关 i/o 2万次 和 将2万个邮箱地址赋予内存效率是一样的?
但第三个代码的效率,楼主测试也是差不多的,这就很难理解了。
因为它也是只有第一个for占用了内存,并且也只开关 i/o 1次,怎么会效率没有区别呢?
费解~
技术问题请到论坛发帖求助!

TOP

回复 16楼 的帖子

测试时间39分49秒
学海无涯

TOP

我在此对于我在测试阶段的感想吧!我现在对于超长文本每次大家提供的代码我都测试,从batman最早的代码到现在,几乎每个都在40分钟测试了大概10多次了吧,个人感觉测试环境主要是机器配置的影响,跟是否浏览网页,是否还运行bat文件没有太大的关系,只要你内存足够,未满负荷,就没有太多的影响,甚至在测试自己原代码的时候,跟随风谈到ping的问题,曾开了另外3个cmd窗口测试ping的时间问题,结果最后顶楼我那个原始代码的测试时间还是最短的,曾截图发在群里时间为:37 分39秒,当然如果哪位有时间,我仍希望cpu内存足够的空机做测试,以便于更接近于科学,顺便证明一下以上我说的是否正确,毕竟一切都在于研究探索发现嘛
学海无涯

TOP

总结了下楼主的测试结果,按19的编号。
代码一、40分钟06秒
代码二、39分29秒
代码三、39分26秒
.
netbenton 16楼的代码 39分49秒
减少了122530次 if defined 判断,但效率却反而更慢了~
难道是因为16楼多用了两对多余的括弧?
这两对括弧比122530次 if defined 判断还要耗时?
越发费解~
技术问题请到论坛发帖求助!

TOP

虽然只开关一次I/O,但仍然是边输出边写入文件。
可以推知,只启用一次IO时,并不是将输出缓存到内存,等到全部输出结束后再一次性写入文件。
如果楼主的测试可信的话,似乎可以得知:可能开关I/O消耗的时间极短,主要耗时花在通过I/O进行数据传输和写文件,尤其是写文件。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

  1. gawk "NR==FNR{a[$1]++}NR>FNR&&!a[$1]++" b.txt a.txt>c.txt
复制代码
第三方命令行工具 gawk.exe 下载地址:
http://bbs.bathome.net/thread-1114-1-1.html
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

做测试的同时干其他事情是有影响的。
如果你把bat窗口最小化了,或者正在操作对内存消耗大的程序,影响更大。系统会自动对后台运行的任务进行优化以节约内存。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

回复 24楼 的帖子

还是第三方强大,1秒就ok了
学海无涯

TOP

回复 25楼 的帖子

我对于一直做这么多相同的测试,并不赞同你的观点,我个人感觉影响微小
学海无涯

TOP

等下我重启机器不开任何东西,做0负荷的测试,就我原代码那个进行测试,原来的时间为37分39秒
测试完以后,我会上来发布测试结果,以真实数据来证明到底其他环境有多大影响



不好意思,大家久等了,我重启机器,所有的程序网页都没开,只是单纯测试我的原代码
测试的时间为 37分26秒

跟我想象的一样,只是差了13秒,从总体时间来考虑,也就是开其它程序,网页,或者bat对结果的影响是微小的!

[ 本帖最后由 jackerloo2009 于 2009-6-27 16:26 编辑 ]
学海无涯

TOP

用括号括起来进行输出确实是一行一行输出,可以这样验证:
  1. @echo off
  2. (
  3.   echo a
  4.   pause 打开 output.txt 会发现已经输出了 a 和 pause 的提示。
  5.   echo b
  6. ) > output.txt
复制代码

TOP

回复 24楼 的帖子

!a[$1]++

百思不得其解,能解释下么?
技术问题请到论坛发帖求助!

TOP

返回列表