簡體   English   中英

如何提高迭代循環性能

[英]How to improve iterative loop performance

所以我試圖遍歷一組數據並創建一個結果樹,顯示所有不同的路徑,我終於成功了,但它運行得很慢,從我的測試來看,這是因為重復搜索 function由於 function 無法確定最終結果是否與標准 windows 匹配,因此最后的附加正則表達式匹配。 如何檢查根調用以過濾以 windows 開頭的結果:以及如何刪除重復搜索 function。 我的猜測是我可以制作一個只包含名稱/父值的新哈希表並使用它,但我已經使用這個概念玩了幾個小時,沒有任何運氣。

當前工作代碼。

Function New-CategoryTree {
    Param (
        $Categories
    )

    $GetParentCategory = [ScriptBlock]::Create({
        Param(
            [psobject]$Category
        )
        
        #Examine the parentCategory field and see if it matches certain criteria.
        Switch ($Category.parentCategory.ref) {
            { $_ -match "^windows:([a-zA-Z_\\ 1-9]+)$" } { #if Parent Category matches 'Windows:*'
                Return "$($Category.parentCategory.ref)\$($Category.name)"
            }
            { [String]::IsNullOrWhiteSpace($_) } { #If pareent
                Return
            }
            Default {
                Return ("$(& $GetParentCategory -Category ($Categories.where({$_.name -eq $Category.parentCategory.ref})))\$($Category.name)")
            }
        }
    })

    New-Variable -Name Result -Value (New-Object -TypeName System.Collections.ArrayList)
    New-Variable -Name NewCategories -Value (New-Object -TypeName System.Collections.ArrayList)
    ForEach ($Category in $Categories) {
        [Void]$NewCategories.Add((& $GetParentCategory -Category $Category))
    }

    ForEach ($Category in $NewCategories) {
        ([Regex]::Match($Category,'^windows:([a-zA-Z_\\ 1-9]+)$').groups[1]).where({$_.success -eq $True}).value |ForEach-Object {[Void]$Result.Add($_)}
    }
    Return $Result
}

數據集

<categories>
    <category name="InternetExplorer" displayName="$(string.InternetExplorer)" explainText="$(string.IE_ExplainCat)">
        <parentCategory ref="windows:WindowsComponents" />
    </category>
    <category name="AdvancedPage" displayName="$(string.AdvancedPage)">
        <parentCategory ref="InternetCPL" />
    </category>
    <category name="InternetCPL_Advanced_Accessibility" displayName="$(string.InternetCPL_Advanced_Accessibility)">
        <parentCategory ref="AdvancedPage" />
    </category>
    <category name="InternetCPL_Advanced_International" displayName="$(string.InternetCPL_Advanced_International)">
        <parentCategory ref="AdvancedPage" />
    </category>
    <category name="InternetCPL_Advanced_Security" displayName="$(string.InternetCPL_Advanced_Security)">
        <parentCategory ref="AdvancedPage" />
    </category>
</categories>

預計 Output

WindowsComponents\InternetExplorer
WindowsComponents\RSS_Feeds
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_Accessibility
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_International
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_Security
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Connections
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Content
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Content\InternetCPL_Content_Certificates
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Privacy
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Programs
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Browsing
WindowsComponents\InternetExplorer\InternetSettings\Advanced\ICWSettings
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Multimedia
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Printing
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Searching
WindowsComponents\InternetExplorer\InternetSettings\Advanced\SignupSettings
WindowsComponents\InternetExplorer\CategoryAppCompat\ScriptPaste
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates\HelpAbout128
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates\UpdateCheck
WindowsComponents\InternetExplorer\CorporateSettings\CodeDownload
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings\GeneralColors
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings\LinkColors
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryNetworkProtocolLockdown\IESF_NPLRest_Category
WindowsComponents\InternetExplorer\AdminApproved
WindowsComponents\InternetExplorer\CategoryAppCompat
WindowsComponents\InternetExplorer\Channels
WindowsComponents\InternetExplorer\CorporateSettings
WindowsComponents\InternetExplorer\DeleteBrowsingHistory
WindowsComponents\InternetExplorer\InternetCPL
WindowsComponents\InternetExplorer\InternetSettings
WindowsComponents\InternetExplorer\Menus
WindowsComponents\InternetExplorer\Persistence
WindowsComponents\InternetExplorer\SecurityFeatures
WindowsComponents\InternetExplorer\Toolbars
WindowsComponents\InternetExplorer\InternetSettings\Advanced
WindowsComponents\InternetExplorer\InternetSettings\AutoCompleteCat
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings
WindowsComponents\InternetExplorer\InternetSettings\Encoding
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_InternetZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_InternetZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_IntranetZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_IntranetZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_LocalMachineZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_LocalMachineZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_RestrictedSitesZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_RestrictedSitesZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_TrustedSitesZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_TrustedSitesZoneLockdown
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_AddOnManagement
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryAJAX
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryBinaryBehaviorSecurityRestriction
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryConsistentMimeHandling
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryInformationBar
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryLocalMachineZoneLockdownSecurity
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryMimeSniffingSafetyFeature
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryMKProtocolSecurityRestriction
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryNetworkProtocolLockdown
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryObjectCachingProtection
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryProtectionFromZoneElevation
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryRestrictActiveXInstall
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryRestrictFileDownload
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryScriptedWindowSecurityRestrictions
WindowsComponents\InternetExplorer\CategoryPrivacy
WindowsComponents\InternetExplorer\CategoryAccelerators
WindowsComponents\InternetExplorer\CategoryCompatView
WindowsComponents\InternetExplorer\InternetCPL\CategoryGeneralPage
WindowsComponents\InternetExplorer\InternetCPL\CategoryGeneralPage\CategoryBrowsingHistory

首先正確處理您的 xml 數據,以便您可以與之交互:

[xml]$categories

然后您可以輕松地顯示它:

[xml]$categories.categories.category | 
    select @{l='ParentCategory';e={$_.ParentCategory.ref}},Name,Displayname

ParentCategory            name                              
--------------            ----                              
windows:WindowsComponents InternetExplorer                  
InternetCPL               AdvancedPage                      
AdvancedPage              InternetCPL_Advanced_Accessibility
AdvancedPage              InternetCPL_Advanced_International
AdvancedPage              InternetCPL_Advanced_Security

根據需要過濾它:

$filtered = [xml]$categories.categories.category | 
    where {$_.ParentCategory.ref -match '^windows:([a-zA-Z_\\ 1-9]+)$'}
$filtered

name             displayName                explainText             parentCategory
----             -----------                -----------             --------------
InternetExplorer $(string.InternetExplorer) $(string.IE_ExplainCat) parentCategory

並將過濾后的 xml 對象導出回字符串,添加外部節點:

$xmlout = '<categories>'+$filtered.outerxml+'</categories>'

經過幾個小時的研究,我偶然發現了 'systems.collections.generic.dictionary' 屬性,它讓我基本上可以創建一個以 PSCustomObject 作為值的哈希表。 這使我能夠創建一個具有可引用名稱的新 object,從而避免使用搜索 function。 結合新的數據類型 + 使用 Streamreader 來獲取文件,我的腳本運行時間從大約 3-5 秒到大約 0.5 秒 ps 忽略了我在代碼中的所有注釋,我正在努力解決 function 哈哈。

Function New-CategoryTree {
    Param (
        $Categories
    )
        
    #Scriptblock that will be used to check if the currently returned object is the root object.
    $GetParentCategory = [ScriptBlock]::Create({
        Param(
            [Parameter(mandatory=$True)]
            $Category,
            [Parameter(mandatory=$True)]
            $Categories
        )
        Switch -regex ($Category.ParentCategory) {
            "^windows:([a-zA-Z_\\ 1-9]+)$" { #if Category matches 'Windows:*' (a.k.a. we are done with the dive.)
                Return "$($Category.ParentCategory)\$($Category.DisplayName)"
            }
            "/^$|\s+/"  { #Check if whitespace or empty.
                Write-Host "Warning: This shouldn't be possible, best guess is ADMX is missconfigured. CategoryName: '$($Category.Name)'."
                #This means its a root category without a parent so just return.
                Return
            }
            Default {#If not root category, then restart the loop to dive 1 layer deeper then eventually retun with parentCategory.DisplayName\Category.DisplayName.
                #If there is no valid parent category then thow a ignorable warning.
                If ([String]::IsNullOrEmpty($Categories["$($Category.ParentCategory)"])) {
                    Write-Host "Warning: $($Category.name) has no valid parent category."
                } Else {
                    Return ("$(& $GetParentCategory -Category $Categories["$($Category.ParentCategory)"] -Categories $Categories)\$($Category.displayName)")
                }
            }
        }
    })

    New-Variable -Name Results -Value (New-Object -TypeName System.Collections.Generic.List[String]) -Force
    ForEach ($Category in $Categories.GetEnumerator()) {
        $Results.Add((& $GetParentCategory -Category $Category.Value -Categories $Categories))
    }
    Return $Results
}

#Start Looping through every ADMX files.
ForEach ($File in $Script.ADMXFiles) {
    #Get content of ADMX file and store results as XML
    Set-Variable -Name ADMXFile      -Value ([xml]((New-Object -TypeName System.IO.StreamReader -ArgumentList $File.FullName,([Text.Encoding]::Default),$False,"10000").ReadToEnd()))
    New-Variable -Name Categories -Value (New-Object -TypeName 'System.Collections.Generic.Dictionary[[string], [PSCustomObject]]') -Force
    $ADMXFile.policyDefinitions.categories.Category |ForEach-Object {
        $Categories.add($_.name,[PSCustomObject]@{
            Name           = $_.name
            DisplayName    = ConvertFrom-StringTable -String $_.displayName -ADMX ($File.BaseName)
            ParentCategory = $_.ParentCategory.ref
        })
    }
    New-CategoryTree -Categories $Categories
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM