ファイルを読み取るPowerShellスクリプトのパフォーマンスが遅すぎる

ナイルズ11

私は現在、ビルドステップの一部としてTeamCityで使用されるPowerShellスクリプトに取り組んでいます。スクリプトは次のことを行う必要があります。

  • フォルダ内の特定の拡張子(.item)を持つすべてのファイルを再帰的にチェックします。
  • 各ファイル(GUIDを含む)の3行目を読み取り、これらの行に重複がないかどうかを確認します。
  • 重複するGUIDを含むファイルのパスをログに記録し、GUID自体をログに記録します。
  • 1つ以上の重複が見つかった場合、TeamCityビルドを失敗させます

私はPowerShellスクリプトにまったく慣れていませんが、これまでのところ、期待どおりの動作をするものを作成しました。

Write-Host "Start checking for Unicorn serialization errors."

$files = get-childitem "%system.teamcity.build.workingDir%\Sitecore\serialization" -recurse -include *.item | where {! $_.PSIsContainer} | % { $_.FullName }
$arrayOfItemIds = @()
$NrOfFiles = $files.Length
[bool] $FoundDuplicates = 0

Write-Host "There are $NrOfFiles Unicorn item files to check."

foreach ($file in $files)
{
    $thirdLineOfFile = (Get-Content $file)[2 .. 2]

    if ($arrayOfItemIds -contains $thirdLineOfFile)
    {
        $FoundDuplicates = 1
        $itemId = $thirdLineOfFile.Split(":")[1].Trim()

        Write-Host "Duplicate item ID found!"
        Write-Host "Item file path: $file"
        Write-Host "Detected duplicate ID: $itemId"
        Write-Host "-------------"
        Write-Host ""
    }
    else
    {
        $arrayOfItemIds += $thirdLineOfFile
    }
}

if ($foundDuplicates)
{
    "##teamcity[buildStatus status='FAILURE' text='One or more duplicate ID's were detected in Sitecore serialised items. Check the build log to see which files and ID's are involved.']"
    exit 1
}

Write-Host "End script checking for Unicorn serialization errors."

問題は:それは非常に遅いです!このスクリプトでチェックする必要のあるフォルダーには、現在14.000を超える.item-filesが含まれており、その量は今後も増え続ける可能性があります。非常に多くのファイルを開いて読み取ることは大規模な操作であることを理解していますが、完了するまでに約30分かかるとは思っていませんでした。これは、すべての(スナップショット)ビルドのビルド時間が30分長くなることを意味するため、長すぎます。これは許容できません。スクリプトが最大で数分で完了することを望んでいました。

これを行うためのより速いアプローチがないことを私はおそらく信じることができません..したがって、この分野での助けは大歓迎です!

解決

さて、私がこれまでに受け取った3つの答えすべてが、これで私を助けてくれたと言わなければなりません。私は最初に.NETFrameworkクラスを直接使用することから始め、次に辞書も使用して増大する配列の問題を解決しました。自分のスクリプトを実行するのにかかった時間は約30分でしたが、.NETFrameworkクラスを使用するとわずか2分に短縮されました。辞書ソリューションを使用した後も、わずか6秒または7秒になりました。私が使用する最後のスクリプト:

Write-Host "Start checking for Unicorn serialization errors."

[String[]] $allFilePaths = [System.IO.Directory]::GetFiles("%system.teamcity.build.workingDir%\Sitecore\serialization", "*.item", "AllDirectories")
$IdsProcessed = New-Object 'system.collections.generic.dictionary[string,string]'
[bool] $FoundDuplicates = 0
$NrOfFiles = $allFilePaths.Length

Write-Host "There are $NrOfFiles Unicorn item files to check."
Write-Host ""

foreach ($filePath in $allFilePaths)
{
    [System.IO.StreamReader] $sr = [System.IO.File]::OpenText($filePath)
    $unused1 = $sr.ReadLine() #read the first unused line
    $unused2 = $sr.ReadLine() #read the second unused line
    [string]$thirdLineOfFile = $sr.ReadLine()
    $sr.Close()

    if ($IdsProcessed.ContainsKey($thirdLineOfFile))
    {
        $FoundDuplicates = 1
        $itemId = $thirdLineOfFile.Split(":")[1].Trim()
        $otherFileWithSameId = $IdsProcessed[$thirdLineOfFile]

        Write-Host "---------------"
        Write-Host "Duplicate item ID found!"
        Write-Host "Detected duplicate ID: $itemId"
        Write-Host "Item file path 1: $filePath"
        Write-Host "Item file path 2: $otherFileWithSameId"
        Write-Host "---------------"
        Write-Host ""
    }
    else
    {
        $IdsProcessed.Add($thirdLineOfFile, $filePath)
    }
}

if ($foundDuplicates)
{
    "##teamcity[buildStatus status='FAILURE' text='One or more duplicate ID|'s were detected in Sitecore serialised items. Check the build log to see which files and ID|'s are involved.']"
    exit 1
}

Write-Host "End script checking for Unicorn serialization errors. No duplicate ID's were found."

みんなありがとう!

マーティンマート

Get-ChildItemやGet-Contentなどの高レベルのコマンドを使用した場合にPowerShellが正確に何を行うかは明確ではありません。したがって、私はそれについてより明確にし、.NETフレームワーククラスを直接使用します。

を使用してフォルダ内のファイルのパスを取得します

[String[]] $files = [System.IO.Directory]::GetFiles($folderPath, "*.yourext")

次に、Get-Contentを使用するのではなく、各ファイルを開いて最初の3行を読み取ります。そのようです:

[System.IO.StreamReader] $sr = [System.IO.File]::OpenText(path)
[String]$line = $sr.ReadLine()
while ($line -ne $null)
{
  # do your thing, break when you know enough
  # ...
  [String]$line = $sr.ReadLine()
}
$sr.Close()

私は1つか2つの間違いを犯したかもしれません、私はあまりにも怠惰に立ち上がってPCでこれをテストします。

また、使用するファイルが少なくなるようにビルドシステムを再設計することを検討することをお勧めします。14000ファイルと成長は不要のようです。一部のデータをより少ないファイルに統合できる場合は、パフォーマンスにも大いに役立つ可能性があります。

重複するGUIDをチェックするには、ファイル名を文字列として、Dictionary <Guid、String>クラスを使用します。次に、重複が見つかった場合は、どこに重複があるかを報告できます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ファイルを読み取るPowerShellスクリプトのパフォーマンスが遅すぎる

分類Dev

rsyncの進行状況を読み取り、遅すぎる場合はファイルをベイルするBashスクリプト

分類Dev

Pythonスクリプトのパフォーマンスの問題:テキストファイルを読み取り、重複を削除します

分類Dev

Node.jsのパフォーマンス-ファイルを1回またはリクエストごとに読み取る

分類Dev

パスにスペースがあるファイルを読み取るBashスクリプト

分類Dev

クリアテキストファイルの読み取りのパフォーマンスの向上

分類Dev

スクリーンリーダーがデフォルトのマークアップ要素の指示を読み取らないようにする

分類Dev

設定ファイルの読み取り/フォーマットを行うシェルスクリプト

分類Dev

行を読み取り、ファイル内のマトリックスからスペースを削除する

分類Dev

ファイルからコマンドを読み取るスクリプトを期待する

分類Dev

ファイルを読み取ってコマンドを実行するbashスクリプト

分類Dev

パフォーマンス:Pythonでファイルを読み取る最速の方法

分類Dev

ファイルから読み取り、コマンドを実行するBashスクリプト

分類Dev

ファイルから数値を読み取り、数値がX値以上の場合にコマンドを実行するBashスクリプト

分類Dev

クリーンでパフォーマンスの高い方法でファイルから部分的にのみ読み取る

分類Dev

jsonファイルを読み取るAzureAutomationスクリプト

分類Dev

Javaの場合:ネットワークパスから読み取る際の「開いているファイルが多すぎます」エラー

分類Dev

Springブートアプリケーションでマニフェストファイルを読み取る

分類Dev

Javaでマルチパートファイルの入力ストリームの内容を読み取る方法

分類Dev

read()は、O_DIRECTフラグがオンになっているファイルをランダムに読み取り、32 MBのファイルサイズで深刻なパフォーマンスヒットを取得しますか?

分類Dev

ファイルを読み取るときに、スクリプトが2番目のforループをスキップする

分類Dev

異なるコンパイラでの読み取り書き込みFortran直接アクセスフォーマットされていないファイル

分類Dev

フォームボタン別のファイルからPowerShellスクリプトを読み込む

分類Dev

Android Java:zipファイルからwebview / stringへのファイルの読み取り、ZipInputStreamが読み取りパフォーマンスを制限するのはなぜですか?

分類Dev

Azure DevOpsのリリースパイプラインのアーティファクトのディレクトリパスを読み取る方法は?

分類Dev

キーが別のユーザー入力変数にあるUnixスクリプトでプロパティファイルを読み取る方法

分類Dev

アイテムを1回だけ読み取る必要がある場合、ルックアップ後にC#ディクショナリからアイテムを削除することによるパフォーマンス上の利点

分類Dev

xarrayがパフォーマンスクリティカルなコードには遅すぎる

分類Dev

CurrentRegion.SpecialCells(xlCellTypeVisible)が遅すぎる-パフォーマンスを改善するためのヒント?

Related 関連記事

  1. 1

    ファイルを読み取るPowerShellスクリプトのパフォーマンスが遅すぎる

  2. 2

    rsyncの進行状況を読み取り、遅すぎる場合はファイルをベイルするBashスクリプト

  3. 3

    Pythonスクリプトのパフォーマンスの問題:テキストファイルを読み取り、重複を削除します

  4. 4

    Node.jsのパフォーマンス-ファイルを1回またはリクエストごとに読み取る

  5. 5

    パスにスペースがあるファイルを読み取るBashスクリプト

  6. 6

    クリアテキストファイルの読み取りのパフォーマンスの向上

  7. 7

    スクリーンリーダーがデフォルトのマークアップ要素の指示を読み取らないようにする

  8. 8

    設定ファイルの読み取り/フォーマットを行うシェルスクリプト

  9. 9

    行を読み取り、ファイル内のマトリックスからスペースを削除する

  10. 10

    ファイルからコマンドを読み取るスクリプトを期待する

  11. 11

    ファイルを読み取ってコマンドを実行するbashスクリプト

  12. 12

    パフォーマンス:Pythonでファイルを読み取る最速の方法

  13. 13

    ファイルから読み取り、コマンドを実行するBashスクリプト

  14. 14

    ファイルから数値を読み取り、数値がX値以上の場合にコマンドを実行するBashスクリプト

  15. 15

    クリーンでパフォーマンスの高い方法でファイルから部分的にのみ読み取る

  16. 16

    jsonファイルを読み取るAzureAutomationスクリプト

  17. 17

    Javaの場合:ネットワークパスから読み取る際の「開いているファイルが多すぎます」エラー

  18. 18

    Springブートアプリケーションでマニフェストファイルを読み取る

  19. 19

    Javaでマルチパートファイルの入力ストリームの内容を読み取る方法

  20. 20

    read()は、O_DIRECTフラグがオンになっているファイルをランダムに読み取り、32 MBのファイルサイズで深刻なパフォーマンスヒットを取得しますか?

  21. 21

    ファイルを読み取るときに、スクリプトが2番目のforループをスキップする

  22. 22

    異なるコンパイラでの読み取り書き込みFortran直接アクセスフォーマットされていないファイル

  23. 23

    フォームボタン別のファイルからPowerShellスクリプトを読み込む

  24. 24

    Android Java:zipファイルからwebview / stringへのファイルの読み取り、ZipInputStreamが読み取りパフォーマンスを制限するのはなぜですか?

  25. 25

    Azure DevOpsのリリースパイプラインのアーティファクトのディレクトリパスを読み取る方法は?

  26. 26

    キーが別のユーザー入力変数にあるUnixスクリプトでプロパティファイルを読み取る方法

  27. 27

    アイテムを1回だけ読み取る必要がある場合、ルックアップ後にC#ディクショナリからアイテムを削除することによるパフォーマンス上の利点

  28. 28

    xarrayがパフォーマンスクリティカルなコードには遅すぎる

  29. 29

    CurrentRegion.SpecialCells(xlCellTypeVisible)が遅すぎる-パフォーマンスを改善するためのヒント?

ホットタグ

アーカイブ