mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 18:57:19 +02:00
CmdPal: Add precomputed fuzzy string matching to Command Palette (#44090)
## Summary of the Pull Request This PR improves fuzzy matching in Command Palette by: - Precomputing normalized strings to enable faster comparisons - Reducing memory allocations during matching, effectively down to zero It also introduces several behavioral improvements: - Strips diacritics from the normalized search string to improve matching across languages - Suppresses the same-case bonus when the query consists entirely of lowercase characters -- reflecting typical user input patterns - Allows skipping word separators -- enabling queries like Power Point to match PowerPoint This implementation is currently kept internal and is used only on the home page. For other scenarios, the `FuzzyStringMatcher` from `Microsoft.CommandPalette.Extensions.Toolkit` is being improved instead. `PrecomputedFuzzyMatcher` offers up to a 100× performance improvement over the current `FuzzyStringMatcher`, and approximately 2–5× better performance compared to the improved version. The improvement might seem small, but it adds up and becomes quite noticeable when filtering the entire home page—whether the user starts a new search or changes the query non-incrementally (e.g., using backspace). <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #45226 - [x] Closes: #44066 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
This commit is contained in:
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Core.Common.Helpers;
|
||||
using Microsoft.CmdPal.Core.Common.Text;
|
||||
using Microsoft.CmdPal.Ext.Apps.Commands;
|
||||
using Microsoft.CmdPal.Ext.Apps.Helpers;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
@@ -14,7 +15,7 @@ using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.Apps.Programs;
|
||||
|
||||
public sealed partial class AppListItem : ListItem
|
||||
public sealed partial class AppListItem : ListItem, IPrecomputedListItem
|
||||
{
|
||||
private readonly AppCommand _appCommand;
|
||||
private readonly AppItem _app;
|
||||
@@ -25,6 +26,35 @@ public sealed partial class AppListItem : ListItem
|
||||
private InterlockedBoolean _isLoadingIcon;
|
||||
private InterlockedBoolean _isLoadingDetails;
|
||||
|
||||
private FuzzyTargetCache _titleCache;
|
||||
private FuzzyTargetCache _subtitleCache;
|
||||
|
||||
public override string Title
|
||||
{
|
||||
get => base.Title;
|
||||
set
|
||||
{
|
||||
if (!string.Equals(base.Title, value, StringComparison.Ordinal))
|
||||
{
|
||||
base.Title = value;
|
||||
_titleCache.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string Subtitle
|
||||
{
|
||||
get => base.Subtitle;
|
||||
set
|
||||
{
|
||||
if (!string.Equals(value, base.Subtitle, StringComparison.Ordinal))
|
||||
{
|
||||
base.Subtitle = value;
|
||||
_subtitleCache.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IDetails? Details
|
||||
{
|
||||
get
|
||||
@@ -259,4 +289,10 @@ public sealed partial class AppListItem : ListItem
|
||||
return null;
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public FuzzyTarget GetTitleTarget(IPrecomputedFuzzyMatcher matcher)
|
||||
=> _titleCache.GetOrUpdate(matcher, Title);
|
||||
|
||||
public FuzzyTarget GetSubtitleTarget(IPrecomputedFuzzyMatcher matcher)
|
||||
=> _subtitleCache.GetOrUpdate(matcher, Subtitle);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user