Skip to content

Optimize#8862

Merged
2dust merged 2 commits into2dust:masterfrom
DHR60:optimize
Mar 1, 2026
Merged

Optimize#8862
2dust merged 2 commits into2dust:masterfrom
DHR60:optimize

Conversation

@DHR60
Copy link
Copy Markdown
Contributor

@DHR60 DHR60 commented Feb 28, 2026

  • 放宽组类型限制,允许作为前置/落地/路由规则节点
  • 从 List indexId 中读取 List 时使用 GetProfileItemsOrderedByIndexIds,大幅度减小读取数据库次数。上次测的 2000 个节点读取耗时约减小了 85%。400 ms -> 50 ms

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

本 PR 旨在放宽“组类型”节点在前置/落地/路由规则等场景中的选择限制,并通过批量按 IndexId 读取 ProfileItem 来显著减少数据库访问次数,从而提升大规模节点场景下的性能。

Changes:

  • 调整多个选择窗口的 ConfigType 过滤逻辑,允许选择组类型相关节点(仅排除 Custom)。
  • 在多个 ViewModel/Manager 中将逐个 GetProfileItem 查询改为批量查询并按输入 IndexId 顺序返回。
  • 新增 AppManager.GetProfileItemsOrderedByIndexIds 以支持“按 IndexId 列表顺序”获取 ProfileItem 列表。

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
v2rayN/v2rayN/Views/SubEditWindow.xaml.cs 放宽前置/落地选择的类型过滤(仅排除 Custom)
v2rayN/v2rayN/Views/AddGroupServerWindow.xaml.cs 放宽组节点添加子节点时的类型过滤(统一仅排除 Custom)
v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml.cs Desktop 端同步放宽前置/落地选择过滤
v2rayN/v2rayN.Desktop/Views/AddGroupServerWindow.axaml.cs Desktop 端同步放宽组节点添加子节点过滤
v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs 选中项读取改为批量按 IndexId 获取,减少 DB 次数
v2rayN/ServiceLib/ViewModels/ProfilesSelectViewModel.cs 多选读取改为批量按 IndexId 获取,减少 DB 次数
v2rayN/ServiceLib/ViewModels/AddGroupServerViewModel.cs 初始化子节点列表改为批量按 IndexId 获取,减少 DB 次数
v2rayN/ServiceLib/Manager/GroupProfileManager.cs Cycle 检测与子节点获取路径改为批量查询/按序返回
v2rayN/ServiceLib/Manager/AppManager.cs 新增 GetProfileItemsOrderedByIndexIds 承载批量按序读取能力

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +253 to +266
var idList = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList();
if (idList.Count == 0)
{
return [];
}

var items = await SQLiteHelper.Instance.TableAsync<ProfileItem>()
.Where(it => idList.Contains(it.IndexId))
.ToListAsync();
var itemMap = items.ToDictionary(it => it.IndexId);

return idList.Select(id => itemMap.GetValueOrDefault(id))
.Where(item => item != null)
.ToList();
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetProfileItemsOrderedByIndexIds calls Distinct() on the incoming indexIds, which removes duplicate ids. Previously, call sites that built ordered lists (e.g., group ChildItems ordering) would preserve duplicates by iterating the original id list. If duplicates are meaningful (e.g., weighting / repeated nodes), this changes behavior; consider keeping the original idList for ordering and using a separate distinct set only for the DB query.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这边就不去重了?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

去重应该更合理些

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但是是否存在一个可能,用户是故意添加的重复的呢?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

那就不改了

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

并且这玩意也不是严格对应的,会跳过某些无效项,也不应该直接下标访问,注释没写

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但是是否存在一个可能,用户是故意添加的重复的呢?

先不管了吧,重复的没什么意义,有人说了再改吧

Comment on lines +251 to +255
public async Task<List<ProfileItem>> GetProfileItemsOrderedByIndexIds(IEnumerable<string> indexIds)
{
var idList = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList();
if (idList.Count == 0)
{
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method signature takes IEnumerable<string> indexIds, but several new call sites pass Select(sp => sp?.IndexId) which is naturally an IEnumerable<string?> and can contain nulls. Since the implementation already filters out null/empty ids, consider changing the parameter type to IEnumerable<string?> (or accepting nullable and guarding) to better reflect actual usage and avoid nullability mismatches.

Copilot uses AI. Check for mistakes.
var itemMap = items.ToDictionary(it => it.IndexId);

return idList.Select(id => itemMap.GetValueOrDefault(id))
.Where(item => item != null)
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idList.Select(id => itemMap.GetValueOrDefault(id)).Where(item => item != null).ToList() relies on a null-filter to satisfy the List<ProfileItem> return type. To keep the non-null contract explicit (and resilient if nullable analysis is enabled later), consider using OfType<ProfileItem>() or null-forgiving after the filter so the resulting list is statically non-nullable.

Suggested change
.Where(item => item != null)
.OfType<ProfileItem>()

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个刚开始的写法就是 .OfType<ProfileItem>() 来着,ReSharper 直接冒绿光让我改成 .Where(item => item != null)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

按编辑器的提示吧。 ai 有时候会弄过时的方案

@2dust 2dust merged commit a71ebbd into 2dust:master Mar 1, 2026
4 checks passed
@DHR60 DHR60 deleted the optimize branch March 1, 2026 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants