📂
batファイル、途中処理で処理は早くなるの?
こんなのを書きました。
これ、変数が入った瞬間に実行したら早いのでは?
ということで試していきましょう!
コード
処理時間を調べるコードはこちらを使いました。
t1.bat
@echo off
setlocal enabledelayedexpansion
set start_time=%time%
rem 実行を入力
if "%1"=="" (set c=1) else (set c=%1)
for /l %%i in (1,1,%c%) do (
for /F "delims=" %%f in ('dir %CD%\in /b /o:-D') do set fname=%%f
move %CD%\in\!fname! %CD%\out
)
set end_time=%time%
echo %start_time%
echo %end_time%
t2.bat
@echo off
setlocal enabledelayedexpansion
set start_time=%time%
rem 実行を入力
if "%1"=="" (set c=1) else (set c=%1) & set /a i=0
for /F "delims=" %%f in ('dir %CD%\in /b /o:-D') do (set fname=%%f
move %CD%\in\!fname! %CD%\out & set /a i+=1
if !i! EQU !c! ( goto skip )
)
:skip
set end_time=%time%
echo %start_time%
echo %end_time%
a.py
for i in range(1000):
with open(f"in\{i}.txt","w") as f:
f.write(f"{i}")
dd.py
del in\*.txt
del out\*.txt
t1が旧コード、t2が新コードです。
時間計測をできるようにし、カレントディレクトリのinフォルダーにあるテキストファイルをoutフォルダーに移動するように変更しています。
また、t2はexit /b
を行っているので、goto skip
に変更しました。
動作確認
> ./t1.bat
1 個のファイルを移動しました。
1:55:47.57
1:55:47.71
> ./t2.bat
1 個のファイルを移動しました。
1:55:48.65
1:55:48.72
処理時間はt1が0.14秒、t2が0.07秒となりました。
この時点で結果が見えそうですが・・・まぁいいでしょう。
検証
a.pyで作成した1000個のテキストファイルを移動させます。
> ./t1.bat 1000
1 個のファイルを移動しました。
~~~~~
1 個のファイルを移動しました。
1:56:54.81
1:57:57.05
> ./t2.bat 1000
1 個のファイルを移動しました。
~~~~~
1 個のファイルを移動しました。
1:58:20.53
1:58:22.49
処理時間はt1が57.76秒、t2が1.96秒となりました。
結論
t1は後半になるにつれスクロールが早くなりました。一方でt2は最初から爆速で流れていきました。
すごい最適化されましたね。
おまけ
batch、実はネストしたfor文でgotoが使えません。breakも不可能です。gotoが実質的なbreakなのにね。
使えないよ!.bat
@echo off
for %%i in (1,2,3) do (
for %%j in (4,5,6) do (
echo %%j
goto a
)
:a
echo %%i
)
これを実行するとこのようになると思いますよね?
1
4
5
6
2
4
5
6
3
4
5
6
でもなりません。
4
%i
・・・それがなんだって話ですね。
なぜこの内容を打ったかというと、最初にこのようなコードを実装しようとしていました。最終的にexit \b
を使うことにしました。goto :EOF
でもいいです。
gotoで実装したい人は参考になるサイトを貼っておきます。
batchは人類には早すぎるすばらしいクソ言語です!
まぁ作られた当時のマシンスペックを考えると妥当かな・・・。
参考文献
更新履歴
コードの調整。それにともない再検証。
Discussion