2013-02-12 59 views
1

我的一位朋友要求我製作一個程序,可以打印一串隨機的1和0的字符串,像時尚的矩陣。我同意了,併成功地編寫批處理程序具有所需的輸出,但它那種跑的慢,如果有一種方法,我可以使它更有效我如何讓這個批處理程序更高效

set count=0 

:loopassign 
if %count%==80 goto show 
set/a count=%count%+1 
set/a value=%random% %% 2 
set number%count%=%value% 
goto loopassign 

:show 
echo {    %number1%%number2%%number3%%number4%%number5%%number6%%number7%%number8%%number9%%number10%%number11%%number12%%number13%%number14%%number15%%number16%%number17%%number18%%number19%%number20%%number21%%number23%%number24%%number25%%number26%%number27%%number28%%number29%%number30%%number31%%number32%%number33%%number43%%number44%%number45%%number46%%number47%%number48%%number49%%number50%%number51%%number52%%number53%%number54%%number55%%number56%%number57%%number58%%number59%%number60%%number61%%number62%%number63%%number64%%number65%%number66%%number67%%number68%%number69%%number70%%number71%%number72%%number73%%number74%%number75%%number76%%number77%%number78%%number79%%number80% } 
set count=0 
goto loopassign 

回答

1

我想知道的主要耗時部分是goto loopassign
這可以用FOR/L循環代替。

該循環比goto更好,因爲在搜索標籤時不再需要掃描整個文件。
而for-block內部的代碼被緩存並且只被解析一次,因此執行速度更快。

對單個字符使用單個行變量而不是80個變量僅用於可維護性。

@echo off 
setlocal enableDelayedExpansion 
set count=0 

:loopassign 
set "line=" 
for /L %%n in (1,1,80) do (
    set /a "value=!random! & 1" 
    set "line=!line!!value!" 
) 

:show 
echo {    !line! } 
goto loopassign 

更多改進的速度變

您可以輕鬆地加速它更用一個簡單的把戲在每個循環四個,而不是一個字符時生成,所以你只需要20環爲單行。

for /L %%n in (1,1,20) do (
    set /a "n=!random! & 15,m=10000+(n&8)*125+(n&4)*25+(n&2)*5+(n & 1)" 
    set "ln=!ln!!m:~-4!" 
) 

這似乎是快三倍

+0

+1,你打敗了我,但我無論如何發佈了幾乎相同的東西,外部無限FOR循環。 – dbenham 2013-02-12 20:20:30

+0

+1對你來說,外環不會顯着提高速度,但是輕咬技術快三倍:-) – jeb 2013-02-12 20:37:44

+0

哦 - 這是討厭的。我喜歡它:)一段時間以來,我認爲你可以每循環多達9位數字,但是我記得'%random%'maxes在32767.爲什麼'&15'?這似乎是不必要的。 – dbenham 2013-02-12 21:28:19

1

你應該瞭解

  • FOR循環:從命令提示符HELP FOR類型。特別是,您需要FOR/L選項

  • 延遲擴展:類型HELP SET從命令提示符。關於延期擴張的部分大約是幫助的一半。

這是一個使用2個FOR/L循環的解決方案。外循環是無限的,因爲它永遠不會增加計數器。

@echo off 
setlocal enableDelayedExpansion 
for /l %%Z in (0 0 1) do (
    set "ln=" 
    for /l %%N in (1 1 80) do (
    set /a "n=!random! %% 2" 
    set "ln=!ln!!n!" 
) 
    echo {    !ln! } 
) 
exit /b 
1

我喜歡速度測試程序!我想下面的礦井會更快...

@echo off 
setlocal EnableDelayedExpansion 

rem Create a Decimal-to-Binary conversion table for values from 0 to 15 
set dec=0 
for %%n in (0000 0001 0010 0011 0100 0101 0110 0111 
      1000 1001 1010 1011 1100 1101 1110 1111) do (
    set bin[!dec!]=%%n 
    set /A dec+=1 
) 

rem Repeat the loop 5 times per line 
set line= 
for /L %%n in (1,1,5) do (
    rem Generate 4 groups of 4 bits per cycle 
    set /A "G1=(n=!random!)&15, G2=(n>>=(G1&3)+1)&15, G3=(n>>=4)&15, G4=(n>>4)&15" 
    for /F "tokens=1-4" %%a in ("!G1! !G2! !G3! !G4!") do (
     set line=!line!!bin[%%a]!!bin[%%b]!!bin[%%c]!!bin[%%d]! 
    ) 
) 
echo {    %line%} 

安東尼

編輯:我稍微修改了表達,以避免在80二進制位5日線固定位置零。

+0

不錯,但我想最高位始終爲0,因爲%random%只使用15位 – jeb 2013-02-16 11:45:59

+0

@jeb:哎呀,你說得對,jeb!這在80個二進制數字的5個固定位置產生零。我用一個小技巧解決了這個問題;-) – Aacini 2013-02-16 14:36:56