[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
我在想,如果乘法是通过加法实现的,那1*10000000和100000000*1的效率是否有别呢?对人来说,这是荒谬的,但是假如电脑是很死板的把X加N次,那二者效率很可能有所不同,当然了,估计就算真的是把某个数加N次,也很可能是先判断二者大小
手上尚无测试结果,暂且中立

TOP

构造了两个个数十兆的超大bat,有了理论支持,果断反方:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (1 40000) do (
  3. set s=%%a*%%a
  4. set /a n+=1
  5. for /l %%a in (1 1 9) do set s=!s!,!s!
  6. (
  7. echo @echo off
  8. echo echo %%time%%
  9. for /l %%l in (1 1 10000) do echo set /a !s!
  10. echo echo %%time%%
  11. echo pause)>test!n!.bat
  12. )
  13. pause
复制代码
测试结果(进行了两次):
test1.bat   20.08秒  19.07秒
test2.bat   28.60秒  28.67秒

这很说明问题了,当然了,这是上万次的set叠加才有这么明显的落差,少量使用时差别必定不明显。可惜没时间进行大量测试,无法描绘函数图象,否则应可猜测set /a的工作原理

TOP

又做了几个测试:

1*1000000,1000000*1
没有大于0.3秒的差别,但是几次测试,后者始终稍快,说明计算前可能并未比较数字大小

而805306366*2却比127867*12596(乘积均为1610612732)
前者快了近两秒,说明确实与复杂度有关,看来有可能真的是用加法,不过究竟具体操作的时候倍增还是指数增长就不得而知了。

536870912*3,1073741823*3(两个大数分别为10000.....00和11111.....11,二进制位数相同)
没有大于0.3秒的差别,数次测试中,前者始终稍快,说明速度和二进制形态或者十进制字节数有关。

1073741824/2,2147483647/2(同上,只比前一个例子的数多一位二进制位数)
前者快了将近半秒,说明同样的字节(包括十进制和二进制)长度下,速度可能由这个数的二进制形态决定。

TOP

楼上考虑过for /l循环本身的用时吗?

TOP

不过仔细想想,也许正是因为语句的字符长度不同导致预处理时间相异,所以4楼代码才会有这么明显的差别。
仅仅个人猜测而已,未验证

TOP

但是楼上似乎忽略了set命令本身也有启动耗时,一次计算耗时和一次启动耗时应该相差很大的,我写了以下代码验证,结果证明1*1与1234567890*1234567890的耗时分别为13秒与17秒
  1. @echo off&setlocal enabledelayedexpansion
  2. set s=1*1
  3. title %s%
  4. for /l %%a in (1 1 9) do set s=!s!,!s!
  5. echo %time%
  6. for /l %%i in (1,1,20000) do (
  7.      set /a %s%
  8. )
  9. echo %time%
  10. pause
复制代码

TOP

set本身也有启动耗时,并且应该远远大于计算耗时,所以需要以set /a n*n,n*n的形式来尽量缩小启动用时所占的百分比
我写了一段代码来证明,1*1与1234567890*1234567890耗时分别为13秒与17秒,证明计算耗时是存在的,并且相差很大
  1. @echo off&setlocal enabledelayedexpansion
  2. set s=1234567890*1234567890
  3. title %s%
  4. for /l %%a in (1 1 9) do set s=!s!,!s!
  5. echo %time%
  6. for /l %%i in (1,1,20000) do (
  7.      set /a %s%
  8. )
  9. echo %time%
  10. pause
复制代码

TOP

好吧,那我们来总结一下,暂时把一句set /a的耗时划分为六部分:
1、语块的预处理耗时
2、变量延迟耗时
3、set命令的启动耗时
4、算式的预处理耗时
5、读取变量耗时
6、计算耗时(实际操作的时候不知道是否和第四部分同时完成)
7、赋值耗时

在这几部分中,1、2、3部分的耗时浮动可以多次测试用平均值尽量排除,而第5、7部分在我的测试代码中不存在,也就是说,我们现在争论的焦点是不同情况下“算式的预处理耗时”之间和“计算耗时”之间的差异。
这一点用批处理似乎没办法验证吧?

TOP

这个是我没考虑周全,我原以为读取变量会慢些,所以当时没细想。但是楼上既然知道启动耗时大于一次计算耗时,那为什么一次set中只计算一次呢?这样一来计算耗时之差会被set启动耗时淹没,自然不明显了。我用set /a 1*1,1*1,1*1,1*1....的办法就是为了让计算耗时所占比重最大化。
  1. @echo off&setlocal enabledelayedexpansion
  2. set n=1&set s=n*n
  3. for /l %%a in (1 1 9) do set s=!s!,!s!
  4. title %n%
  5. echo %time%
  6. for /l %%i in (1,1,10000) do (
  7.      set /a %s%
  8. )
  9. echo %time%
  10. pause
复制代码
结果n=1时耗时39秒,n=1234567890时耗时44秒,这又作何解释呢?

TOP

至于15楼的代码,我不懂编程,但是从vbs和bat的差别中猜测编程的计算方法、赋值方式完全不同于bat,所以exe的计算速度远快于cmd,生命游戏就是一个例子,可以exe版和bat版生命游戏来对比出同尺寸图、同样代数的用时

TOP

批处理怎么设值变量类型??

TOP

不懂编程,不过我觉得如果乘法只是加法集合成的函数,那不见得速度一样快

TOP

stop,要想不跑偏必须先统一一下意见,因为以后的讨论可能是以此为前提的:
1、set 命令读取变量时的速度快于预处理解释字符串的速度,也就是说set /a m=n(此时n=1)真的快于set /a m=1吗?
2、set 命令读取变量的速度是否取决于变量的字符串长度?

暂时没时间做实验,证明这两个假设的工作先交给诸位了哈...

TOP

至于set命令内部预处理的耗时,请参考11楼测试结果,虽然结果相同时速度仍有差异,但是预处理并非决定性因素。

TOP

返回列表