Improves Winget search performance by streaming results

Refactors the package search logic to process results as a stream instead of collecting them all in memory first.

This change uses the PowerShell pipeline to transform search results on the fly. This significantly reduces memory usage and improves responsiveness, especially for queries that return a large number of packages.
This commit is contained in:
rbalsleyMSFT
2025-06-18 17:19:57 -07:00
parent f44e06c57e
commit 9b8a6c36db
@@ -27,17 +27,10 @@ function Search-WingetApps {
# Store selected apps from the current view # Store selected apps from the current view
$selectedAppsFromView = @($currentItemsInListView | Where-Object { $_.IsSelected }) $selectedAppsFromView = @($currentItemsInListView | Where-Object { $_.IsSelected })
# Search for new apps # Search for new apps, which are streamed directly as PSCustomObjects
$searchedAppResults = Search-WingetPackagesPublic -Query $searchQuery | ForEach-Object { # with the required properties for performance.
[PSCustomObject]@{ $searchedAppResults = Search-WingetPackagesPublic -Query $searchQuery
IsSelected = $false # New items are not selected by default WriteLog "Found $($searchedAppResults.Count) apps matching query '$searchQuery'."
Name = $_.Name
Id = $_.Id
Version = $_.Version
Source = $_.Source
DownloadStatus = ""
}
}
$finalAppList = [System.Collections.Generic.List[object]]::new() $finalAppList = [System.Collections.Generic.List[object]]::new()
$addedAppIds = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) $addedAppIds = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
@@ -154,17 +147,24 @@ function Search-WingetPackagesPublic {
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[string]$Query [string]$Query
) )
WriteLog "Searching Winget packages with query: '$Query'" WriteLog "Searching Winget packages with query: '$Query'"
try { try {
# Call the shared Find-WinGetPackage function # Stream results directly from Find-WinGetPackage and convert them to simple PSCustomObjects
$results = Find-WinGetPackage -Query $Query -ErrorAction Stop # on the fly using Select-Object with calculated properties. This is significantly faster
WriteLog "Found $($results.Count) packages matching query '$Query'." # for large datasets as it avoids holding complex objects in memory and bypasses the
return $results # expensive formatting system for the raw results.
Find-WinGetPackage -Query $Query -ErrorAction Stop |
Select-Object -Property @{Name = 'IsSelected'; Expression = { $false } },
Name,
Id,
Version,
Source,
@{Name = 'DownloadStatus'; Expression = { '' } }
} }
catch { catch {
WriteLog "Error during Winget search: $($_.Exception.Message)" WriteLog "Error during Winget search: $($_.Exception.Message)"
# Return an empty array or throw, depending on desired UI behavior # Return an empty array or throw, depending on desired UI policy
return @() return @()
} }
} }