From 9b8a6c36db21637ea927a30eb3f57f0b2ac8022f Mon Sep 17 00:00:00 2001 From: rbalsleyMSFT <53497092+rbalsleyMSFT@users.noreply.github.com> Date: Wed, 18 Jun 2025 17:19:57 -0700 Subject: [PATCH] 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. --- .../FFUUI.Core/FFUUI.Core.Winget.psm1 | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Winget.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Winget.psm1 index 9cbbb13..3f82dd6 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Winget.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Winget.psm1 @@ -27,17 +27,10 @@ function Search-WingetApps { # Store selected apps from the current view $selectedAppsFromView = @($currentItemsInListView | Where-Object { $_.IsSelected }) - # Search for new apps - $searchedAppResults = Search-WingetPackagesPublic -Query $searchQuery | ForEach-Object { - [PSCustomObject]@{ - IsSelected = $false # New items are not selected by default - Name = $_.Name - Id = $_.Id - Version = $_.Version - Source = $_.Source - DownloadStatus = "" - } - } + # Search for new apps, which are streamed directly as PSCustomObjects + # with the required properties for performance. + $searchedAppResults = Search-WingetPackagesPublic -Query $searchQuery + WriteLog "Found $($searchedAppResults.Count) apps matching query '$searchQuery'." $finalAppList = [System.Collections.Generic.List[object]]::new() $addedAppIds = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) @@ -154,17 +147,24 @@ function Search-WingetPackagesPublic { [Parameter(Mandatory = $true)] [string]$Query ) - + WriteLog "Searching Winget packages with query: '$Query'" try { - # Call the shared Find-WinGetPackage function - $results = Find-WinGetPackage -Query $Query -ErrorAction Stop - WriteLog "Found $($results.Count) packages matching query '$Query'." - return $results + # Stream results directly from Find-WinGetPackage and convert them to simple PSCustomObjects + # on the fly using Select-Object with calculated properties. This is significantly faster + # for large datasets as it avoids holding complex objects in memory and bypasses the + # 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 { 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 @() } }