我花了一些时间试图在PowerShell应用程序中找到瓶颈,而没有怀疑它只是一个缓慢的参数验证。示例代码说明了问题:
function Test-ValidatePerformance
{
param(
[ValidateNotNullOrEmpty()]
[Byte[]]
$Data
)
$sw.Stop()
Write-Host "Executing after $([Math]::Round($sw.Elapsed.TotalMilliSeconds))ms"
}
function Test-NoValidatePerformance
{
param(
[Byte[]]
$Data
)
$sw.Stop()
Write-Host "Executing after $([Math]::Round($sw.Elapsed.TotalMilliSeconds))ms"
}
$buf = [IO.File]::ReadAllBytes('C:\17MB_FILE.bin')
Write-Host "Calling with validation..."
$sw = [Diagnostics.Stopwatch]::StartNew()
Test-ValidatePerformance $buf
Write-Host "`nCalling without validation..."
$sw = [Diagnostics.Stopwatch]::StartNew()
Test-NoValidatePerformance $buf
输出:
Calling with validation...
Executing after 1981ms
Calling without validation...
Executing after 3ms
我的问题是:为什么[ValidateNotNullOrEmpty()]
如此缓慢(考虑到它的名称状态)它只检查null或空参数?
答案 0 :(得分:4)
当您将(大多数)验证属性添加到集合时,它将应用于集合中的每个项目;而不是整个集合,因此将针对每个字节运行验证。
mklement0提出an open issue on GitHub about this very thing。
测试它不是空的最简单方法就是使参数成为必需参数;那时将不接受空数组:
function Test-ValidatePerformance
{
param(
[Parameter(Mandatory)]
[Byte[]]
$Data
)
$sw.Stop()
Write-Host "Executing after $([Math]::Round($sw.Elapsed.TotalMilliSeconds))ms"
}
注意:正如原始海报所指出的那样,Patrick Meinecke已确认in this GitHub issue, there is a bug in Windows PowerShell (fixed in Core), regarding the performance issue with Mandatory parameters。
如果您希望参数是可选的,但如果提供的参数不能为空,则可以改为使用[ValidateCount()]
,这应该很快:
function Test-ValidatePerformance
{
param(
[ValidateCount(1,[int]::MaxValue)]
[Byte[]]
$Data
)
$sw.Stop()
Write-Host "Executing after $([Math]::Round($sw.Elapsed.TotalMilliSeconds))ms"
}
或者您可以执行检入代码而不是使用验证属性。
function Test-ValidatePerformance
{
param(
[Byte[]]
$Data
)
if (-not $Data -and $PSBoundParameters.ContainsKey('Data')) {
throw [System.ArgumentException]'An empty array is not allowed'
}
$sw.Stop()
Write-Host "Executing after $([Math]::Round($sw.Elapsed.TotalMilliSeconds))ms"
}