search this site:

Chaotic Neutral

左にも右にもよらず、自由な生き方探し。

Windows Powershell ― dir -recurse


私のコンピューターのディレクトリH:\temporaryにはファイルがたくさん入っている。

ディレクトリの中のすべてのディレクトリとファイルについての情報を取得するために、Powershellでは
dir -recurseを使うが、重い。試しに、measure-command{dir -recurse}をやってみると、

PS H:\temporary> measure-command {dir -recurse}


Days : 0
Hours : 0
Minutes : 0
Seconds : 23
Milliseconds : 71
Ticks : 230715303
TotalDays : 0.000267031600694444
TotalHours : 0.00640875841666667
TotalMinutes : 0.384525505
TotalSeconds : 23.0715303
TotalMilliseconds : 23071.5303

約24秒。

まあまあに見える、dir -recurseで既にこれだけかかっているのだから、先が思いやられる。

さて、今度は、ディレクトリの中のディレクトリだけを取得してみる。

PS H:\temporary> measure-command{dir -recurse | ?{$_.Mode[0] -eq 'd'}}


Days : 0
Hours : 0
Minutes : 1
Seconds : 51
Milliseconds : 108
Ticks : 1111088565
TotalDays : 0.00128598213541667
TotalHours : 0.03086357125
TotalMinutes : 1.851814275
TotalSeconds : 111.1088565
TotalMilliseconds : 111108.8565

取得したディレクトリの数は162個なのに、かかった時間は2分近い。旧コマンドプロンプトでは約4秒だったことを考えると、機能の充実ぶりを考慮しても、これはいただけない。

そこで、ディレクトリだけを高速で取得する関数を書いてみた。

function global:flistd{
$aList = @()
$aList += dir | ?{$_.Mode -like 'd*'}
$i = 0
while($aList[$i]){
$aList += $aList[$i].GetDirectories()
$i++
}
$aList = $aList | sort LastWriteTime
return $aList
}
PS H:\temporary> measure-command{flistd}


Days : 0
Hours : 0
Minutes : 0
Seconds : 4
Milliseconds : 192
Ticks : 41929840
TotalDays : 4.85299074074074E-05
TotalHours : 0.00116471777777778
TotalMinutes : 0.0698830666666667
TotalSeconds : 4.192984
TotalMilliseconds : 4192.984

驚きの約4秒!

所要時間は1/30くらいにまで短縮された。

同じ要領で、dir -recurseまで高速化してみた。

function global:flist{
$aList = @()
$aList += flistd
$aTemp = dir | ?{$_.Mode -notlike 'd*'}
if($aList){
foreach($i in $aList){
$aTemp += $i.GetFiles()
}
}
$aList += $aTemp
return $aList
}
PS H:\temporary> measure-command {flist}


Days : 0
Hours : 0
Minutes : 0
Seconds : 6
Milliseconds : 731
Ticks : 67318628
TotalDays : 7.79150787037037E-05
TotalHours : 0.00186996188888889
TotalMinutes : 0.112197713333333
TotalSeconds : 6.7318628
TotalMilliseconds : 6731.8628

ファイル数は14094個なので、所要時間が約7秒ってのは神速!

Powershellにはまだまだ最適化の余地がたっぷりある。

ファイル1万個を7秒でスキャン(なのかな?)するってのは相当すごいですね。


記事中「さて、今度は、ディレクトリの中のディレクトリだけを取得してみる。 」の下の青い太線が動いているのですがこれは・・・?

  • 2008年04月27日日
  • URL
  • 弦謳 #dPE4wBkA
  • 編集

Powershellのコマンドレット(コマンド)は遅いですが、Powershellから.NETのクラスライブラリを呼び出すと速いです。今後改良が進めば、Powershellはもっと速くなるってことですね。

「青い太線」は自分の環境じゃ見えません。気になります。

  • 2008年04月27日日
  • URL
  • Lexar #tV7uNBRQ
  • 編集

コメントの投稿

URL
コメント
パスワード
秘密
管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://reviva.blog1.fc2.com/tb.php/969-01060800