powershell初心者です。
前提・実現したいこと
1GBのcsvファイル(大体1000万行)*10ファイルほど処理したい。
情報が足りない、書いていることがおかしい等ありましたらご教授いただけると嬉しいです。
-
処理の内容
-
入力csvの内容
1000万行(1).csv IP,fagafaga,検索文字列 "11.111.11.111","fugafuga","PPPP" "22.222.22.222","hogehoge","OOOO" . . . 1000万行(2).csv IP,fagafaga,検索文字列 "11.111.11.111","fugafuga","OOOO" "33.333.33.333","hogehoge","AAAA" . . .
- 出力csvの内容
IP,重複した数,検索文字列が一致した数 "11.111.11.111","2","2" "22.222.22.222","1","1" "33.333.33.333","1","0"
解決したいこと
処理速度が遅い。
出力結果は意図したものが出力できてますが
環境のせいもあるかもしれませんが、1万行を処理するのに2分ほどかかっています。
1000万行のファイルを処理するには厳しい状態です。
該当のソースコード
フォルダ構成
・検索.ps1
・処理対象データ(フォルダ)
ー1000万行(1).csv
ー1000万行(2).csv
ー1000万行(3).csv
…
ー1000万行(10).csv
powershell
1$sPath = Split-Path -Parent $MyInvocation.MyCommand.Path; 2$outPath = $sPath+'\整形結果.csv'; 3$pkHash = @{}; 4 5get-childItem $sPath"\処理対象データ\" | ForEach-Object { 6 # write-host "ファイル読み込み" 7 8 Get-Content -ReadCount 1 $sPath"\処理対象データ\"$_ -Encoding UTF8| ForEach-Object { 9 10 $LostSeg = 0; 11 $OutofOrder = 0; 12 13 $lineAry = $_ -split '","'; 14 $iP = $lineAry[0]; 15 $s = $lineAry[2]; 16 17 #文字列の検索1 18 if($s.Contains("PPPP")){ 19 $LostSeg = 1; 20 }; 21 #文字列の検索2 22 if($s.Contains("OOOO")){ 23 $OutofOrder = 1; 24 }; 25 26 #IPが既にハッシュテーブルに存在するか確認、存在=すでに存在しているvalueに加算、存在しない=キーの追加 27 $Sequence = $LostSeg + $OutofOrder; 28 if($pkHash.ContainsKey($iP)){ 29 $pkHash.$iP.Count_Out_of_Sequence += $Sequence 30 $pkHash.$iP.Count_Out_of_Packet += 1;#重複IPのカウント 31 }else { 32 $pkHash.Add($iP,@{ 33 Count_Out_of_Sequence = $Sequence 34 Count_Out_of_Packet = 1 35 }; 36 } 37}; 38#csv出力 39$pkHash.GetEnumerator() | 40Select-Object @{N="IP"; E={$_.Key}}, @{N="重複した数"; E={$_.Value.Count_Out_of_Packet}} ,@{N="検索文字列が一致した数"; E={$_.Value.Count_Out_of_Sequence}}| 41Sort-Object Count_Out_of_Sequence -Descending | 42Export-Csv $outPath -Encoding Default -NoTypeInformation 43
まずどの箇所がボトルネックなのか調査したら?
ファイルI/Oに時間がかかってるとかならSSD使うだけで解決するかもしれんし。
メモリは十分にありますか?メモリがあれば並列で処理するのはどうでしょうか?
返答遅くなり、申し訳ないです。
ご協力本当にありがとうございます。
>gentaroさん
Get-DateをファイルI/Oの間に差し込んで1万行のcsvで確認したところ
inは値をメモリに渡さず1行ずつパイプでForeach-Objectに渡しているからか、一瞬で
outは5秒ほどでした。
なので、ループの中身が遅くなる原因かと思いましたが、、どの部分かいまいちわかっていないのでもう少しコード削りながら調べてみることにいたします。
>meg_さん
並列処理というものをできるということを知りませんでした!
メモリは8GBですが、物は試しで調べて書いてみたいと思います。