きっかけ
日次で古くて大きめなファイルをリストアップしたいと思い、はじめはバッチで書いていたのですが、
1. 作成したコードがけっこうな長さになってしまう
2. バッチの実行スピードが思ったよりも速くない
ということで比較のためにPowerShellでも同じ処理を書いてみました。
なかなか面白い結果が出たので内容を以下にまとめてみます。
処理の概要
指定したディレクトリ(例ではN:\share配下)の中から、ファイルサイズが10メガバイト以上かつ更新日が2年以上前のものをリストアップし、結果をテキストファイルに出力する1
環境
Windows Server 2008R2
PowerShellのバージョンは2.0
処理対象のディレクトリはファイルサーバー上にあり、約1,000個のファイルが格納されています
コード
@echo off
rem カッコ内でsetを遅延反映させるためのオプション
setlocal ENABLEDELAYEDEXPANSION
rem 以降、遅延反映させたい変数には$hoge$のかわりに!hoge!と記述
set target_folder=N:\share
set YYYY=%date:~-10,4%
set MM=%date:~-5,2%
set DD=%date:~-2,2%
set /a YYYY=YYYY-2
rem 出力ファイル名(固定名+現在日時.lst)
set output=%~dp0\files_bat_%time:~-11,2%%time:~-8,2%%time:~-5,2%.lst
FOR /F "usebackq delims=" %%F in (`dir /B /S %target_folder%\*.*`) do if %%~zF GTR 10000000 (
set upd_time=%%~tF
set minutes=!upd_time:~-5,2!
set seconds=!upd_time:~-2,2!
rem 更新日付の比較
if "!upd_time!" GTR "%YYYY%/%MM%/%DD% !minutes!:!seconds!" (
rem 新しいファイル
) else (
rem 古いファイル
echo %%F>> %output%
)
)
$targetPath = "N:\share"
$scriptPath = Split-Path $script:myInvocation.MyCommand.path -parent
$output = $scriptPath\files_ps1_$time.lst
$time = Get-Date -Format "HHmmss"
$a = Get-ChildItem -recurse $targetPath
foreach($x in $a)
{
$y = ((Get-Date) - $x.LastWriteTime).Days
if ($y -gt 730 -and $x.PsISContainer -ne $True -and $x.Length -gt 10000000)
{echo $x.fullname | Out-File -filePath $output -Append -encoding Default}
}
※ 厳密にいうと2年前(バッチの処理)と730日前(PowerShellの処理)は違うんじゃないすかと言われそうですが、はい、そのとおりです。。。ざっくり2年間前以前を抽出したかったのでこのようになっています。
処理時間計測結果
バッチ | PowerShell | |
---|---|---|
一回目 | 15.95秒 | 2.02秒 |
二回目 | 15.85秒 | 2.04秒 |
三回目 | 16.20秒 | 2.06秒 |
考察
なぜこれほど実行時間に差が出たのか気になりました。
I/Oがバッチの方が多いのかな???と思ってtaskmgr.exeから調べてみましたが
バッチ | PowerShell | |
---|---|---|
I/O Read | 953,600 byte | 987,525 byte |
I/O Write | 13,802 byte | 21,918 byte |
とほぼ同じくらい・・・
ふむ。
バッチの処理をあらためて見ると、変数に格納したり計算したりしているのでここらが足をひっぱっているのではないかと推測します。冗長なコード⇒それに伴う演算処理量アップな気がします。
とは言え、今回の場合は「ファイルサイズが大きくて古いファイルを見つけるコマンド」にピンポイントで該当するものがなく、「dirコマンド」結果を一個一個「for」の中で処理していますので、どストライクなコマンドがあれば、処理時間はあまり変わらないのではないかとも思います。
今回の結論
バッチ | PowerShell |
---|---|
コードがやや冗長 | コードは簡素 |
処理が遅い | 処理はまあまあ速い2 |