たいがー道場...というのは冗談で、前回の記事Select-Objectを用いて任意の個数ごとにObjectを取り出す例の別解です。 前回のは二重ループ1だったので、今回は別方法を利用します。
こっちは、パフォーマンス上の低下を回避しています。
Foreach-Objectでいってみよう
ぱっと思いつくのはこれですね。
$Items = ps $GroupNum = 20 [ScriptBlock]$ScriptBlock = {(Get-Date).DateTime} $Items | %{$i=1}{$_; if($i % $GroupNum -eq 0){&$ScriptBlock};++$i}
これで、Get-Process (ps)の20個毎にGet-Dateでその時刻が出ます。
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 142 11 1876 2960 89 432 atieclxx 100 6 800 996 25 840 atiesrxx 110 9 8404 7580 38 41.81 5736 audiodg 146 15 2880 1576 76 1492 BingDesktopUpdater 117 11 2060 1588 61 1752 c2c_service 832 94 82304 5304 879 18.45 4412 CCC 30 4 576 368 27 5228 conhost 277 19 8896 2948 408 0.05 6936 CSISYN~1 446 14 2460 1980 68 436 csrss 465 28 2792 11648 243 536 csrss 347 19 9688 14548 86 1116 dasHost 88 7 1672 3176 34 6364 dllhost 241 29 55080 35420 304 976 dwm 103 9 21200 20324 117 20.00 4708 Everything-1.2.1.421b 1752 837 82168 86520 946 119.57 3560 explorer 138 12 2808 8056 105 0.03 7388 FlashUtil_ActiveX 1035 68 161720 82960 518 2,046.06 6736 GOM 2085 88 142320 23400 625 57.21 1908 holLaunchPadOnline 0 0 0 20 0 0 Idle 162 17 3728 3268 101 1.98 4596 IDM 2013年6月13日 5:36:14 1224 306 255600 338020 757 94.71 4796 iexplore 743 71 45424 74752 329 10.62 8288 iexplore 601 39 10184 31664 174 4.23 8444 iexplore 176 13 12396 17752 199 5.60 3616 ImeBroker 203 16 7172 2612 110 1568 IpOverUsbSvc 366 20 4248 3320 95 0.62 800 jusched 292 21 4384 2704 111 0.73 4052 KHALMNPR 917 99 177316 237256 913 227.01 7632 krile 351 18 19132 2436 173 10.65 1100 lightscreen 1169 27 10732 12288 62 628 lsass 274 35 7576 6864 188 52.78 4516 MagicFormation 493 55 41672 9484 716 7.71 5012 mmc 295 34 27212 4356 586 0.34 5024 MOM 494 84 114240 97344 280 2016 MsMpEng 588 63 472556 268884 740 1,982.21 6264 opera 73 7 1040 920 66 0.12 6952 pageant 544 75 164580 205256 1324 277.00 4788 powershell_ise 167 26 26364 2292 514 3668 PresentationFontCache 240 25 22524 16548 211 27.49 3536 RaUI 103 8 1712 6616 73 0.02 9088 RuntimeBroker 2013年6月13日 5:36:14 606 55 30892 10144 661 4076 SearchIndexer 279 11 7316 7828 36 612 services 253 21 6164 2400 133 10.72 1080 SetPoint 639 44 11992 9376 145 4.13 3272 SkyDrive 607 40 65504 34376 222 426.87 4108 Skype 36 2 292 508 5 316 smss 365 20 3864 3156 73 1328 spoolsv 373 43 204328 12356 298 1640 sqlservr 79 9 1428 1336 43 1852 sqlwriter 1090 45 41432 27688 146 372 svchost 393 15 4560 5940 45 732 svchost 527 16 7536 7912 44 772 svchost 842 32 21580 18964 127 884 svchost 2021 81 240268 213240 550 912 svchost 854 42 16016 20292 119 988 svchost 942 86 19592 15088 1542 1152 svchost 473 41 24716 19672 400 1356 svchost 96 10 3364 1332 42 1472 svchost 519 29 10972 14892 94 1688 svchost 137 11 2324 2616 44 1896 svchost 2013年6月13日 5:36:15 137 14 3728 1596 46 1996 svchost 399 32 10716 11440 960 4260 svchost 949 0 136 540 11 4 System 321 342 9764 14512 665 4.10 3592 taskhostex 96 10 1388 1684 48 1936 vmnat 50 7 1116 1328 27 2056 vmnetdhcp 254 17 6872 3252 97 2324 vmware-authd 148 12 2136 2160 71 2124 vmware-usbarbitrator64 74 8 940 696 54 528 wininit 149 8 1728 2052 70 588 winlogon 150 14 5628 15004 117 0.44 4360 WinSCP 118 10 1808 2260 42 5204 wlanext 103 8 1956 1496 32 9652 WmiPrvSE 447 26 8860 8816 103 4384 wmpnetwk 211 10 1456 1232 43 3008 WUDFHost 203 9 1420 1480 43 4840 WUDFHost 292 26 13760 26044 164 0.28 3880 WWAHost 78 7 1144 1200 67 0.02 1200 ZuneLauncher
Foreachでいってみよう
以前のベンチマークでもわかる通り、PowerShellのForeach-Objectは便利ですがパフォーマンス悪いです。
そのため、PowerShellにおいてもう少しましなforeachでやってみましょう。
$Items = ps $GroupNum = 20 [ScriptBlock]$ScriptBlock = {(get-date).DateTime} $i=1 foreach($item in $items) { $item; if($i % $GroupNum -eq 0){&$ScriptBlock};++$i }
Foreach-ObjectとForeachでそんなに違うの?
Foreach-Objectのベンチマークです。
$Items = 1..100000 $GroupNum = 20 [ScriptBlock]$ScriptBlock = {(get-date).DateTime} Measure-Command{ $Items | %{$i=1}{$_; if($i % $GroupNum -eq 0){&$ScriptBlock};++$i} }
Foreachです。
$Items = 1..100000 $GroupNum = 20 [ScriptBlock]$ScriptBlock = {(get-date).DateTime} Measure-Command{ $i=1 foreach($item in $items) { $item; if($i % $GroupNum -eq 0){&$ScriptBlock};++$i } }
結果です。
| 処理 | 処理時間(ms) |
|---|---|
| Foreach-Object | 6659.746 |
| Foreach | 3639.2884 |
-
Select-Objectはそれ自体でループしている↩