現在、ビルドステップの一環としてTeamCityで使用されるPowerShellスクリプトを作成しています。スクリプトは、にあります。PowerShellスクリプトのファイル読み込みのパフォーマンスが低すぎます
- 再帰的(GUIDが含まれている)、各ファイルの3行目を読んで、任意の重複があるかどうかを確認
- 、フォルダ内の特定の拡張子(.item)を持つすべてのファイルをご確認くださいこれらの行では、
- 私はに完全に新しい午前一つ以上の重複が
を発見された場合はチームシティーのビルドを失敗させる重複GUIDを含むファイルのパスを記録し、GUID自体を記録、
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ファイルが含まれており、その量は今後も増加する可能性が非常に高いです。私は非常に多くのファイルを開いたり読んだりするのは大規模な作業だと理解していますが、完了までに約30分かかるとは思いませんでした。これは長すぎます。これは、すべての(スナップショット)ビルドのビルド時間が30分長くなることを意味するためです。これは容認できません。私はスクリプトが最大2分で完了することを期待していました。
私は恐らくこれを行うためのより速いアプローチがないと信じることはできません。この分野のどんな助けも大歓迎です!
ソリューション
は、まあ、私は私がこれまでに受信したすべての3つの答えはこの1つで私を助けたことを言わなければなりません。私はまず、.NETフレームワーククラスを直接使用し始めました。次に、辞書を使用して、増加する配列の問題を解決しました。自分のスクリプトを実行するのに要した時間は約30分で、.NETフレームワーククラスを使用することでわずか2分に短縮されました。 Dictionaryソリューションを使用した後も、わずか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."
すべてに感謝します!
ファイルのIO帯域幅はおそらく制限されています。だから、大部分の時間は(おそらく)ディスクからファイルをドラッグするのに使われています。その場合(エンベロープ計算の後ろでそれを確認できるはずです)、それをスピードアップする最も簡単な方法は、SSDのようなより高速なストレージに移行することです。 –
@Mike Wise:現代のマシンでは14000個のファイルをコピーするのに30分も過ぎるかもしれませんが、そうかもしれません。私はこの場合、ファイルIOはまったく問題ではないと思います。彼のコードは「ビルドステップの一部」なので、コードが実行される直前にすべてのファイルが処理されたり作成されたりするため、すべてがディスクキャッシュに残っている可能性があります。 –