たいがー道場...というのは冗談で、前回の記事Select-Objectを用いて任意の個数ごとにObjectを取り出す例の別解です。
前回のは 二重ループ ( Select-Objectはそれ自体でループしている) だったので、今回は別方法を利用します。
こっちは、パフォーマンス上の低下が回避されています。
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
}
}
結果です。
Foreach-Object : TotalMilliseconds : 6659.746
Foreach : TotalMilliseconds : 3639.2884
ねみゅいのでfunctionはいいや