来源:2026-09-28 性能复审(基于 master@b2ac639)。#199/#213/#222 新增代码的次级浪费点,与失效粒度问题(另 issue)正交。
1. Trie::insert 急切分配 label
src-tauri/crates/mhost-dns/src/trie.rs:174-179:对每个 label 无条件 entry(label.to_string()),即使节点已存在(String 随即被丢弃)。10 万域名 × ~3 label ≈ 每次 rebuild ~30 万次纯浪费 String 分配;3 棵 trie 全量重建时翻倍。另有每域名 1 个 Vec<&str> labels 分配(:145)。
修:match children.get_mut(label) { None => insert, Some(n) => descend }。
2. refresh 单源数据物化 4 次、解析 2 次
src-tauri/src/commands/adblock.rs:738-741 解析 fetched body(每域 to_lowercase 分配);:766-771 再 format!("0.0.0.0 {}", d) + Vec<String> + join 生成 canonical 文本(约 2× body 大小的瞬时分配);写缓存后 persist_and_reload → domains_for_source(:387-399)读回缓存再解析一遍。50 万规则时一次 refresh 约 100MB 级瞬时分配 + 两个完整 parse pass。
修:BufWriter 逐行写 canonical 文本;解析结果 Vec<String> 直接传递或缓存解析形态,避免读回重解析。
3. classify_rules → rebuild 双重插入
classify_rules 先建 HashMap<String, IpAddr> / HashSet<String>,AdBlockEngine::rebuild 再逐条 insert 进 trie:每个域名每次 reload 被复制/哈希两遍。
修:从 parse 输出直接构建 trie,跳过中间 HashMap/HashSet。
4. snapshot() 在 enabled 检查之前
mhost-dns/src/adblock.rs:232-241:adblock 关闭(常见态)时每查询仍付 1 次读锁 + Arc 引用计数。
修:把 enabled.load() 提到 snapshot() 之前。
验证
cargo test --all-features 全绿;rebuild/refresh 路径可加一个分配计数基准(#[global_allocator] counting allocator 或 dhat)证明下降。
1.
Trie::insert急切分配 labelsrc-tauri/crates/mhost-dns/src/trie.rs:174-179:对每个 label 无条件entry(label.to_string()),即使节点已存在(String 随即被丢弃)。10 万域名 × ~3 label ≈ 每次 rebuild ~30 万次纯浪费 String 分配;3 棵 trie 全量重建时翻倍。另有每域名 1 个Vec<&str>labels 分配(:145)。修:
match children.get_mut(label) { None => insert, Some(n) => descend }。2. refresh 单源数据物化 4 次、解析 2 次
src-tauri/src/commands/adblock.rs:738-741解析 fetched body(每域to_lowercase分配);:766-771 再format!("0.0.0.0 {}", d)+Vec<String>+join生成 canonical 文本(约 2× body 大小的瞬时分配);写缓存后persist_and_reload→domains_for_source(:387-399)读回缓存再解析一遍。50 万规则时一次 refresh 约 100MB 级瞬时分配 + 两个完整 parse pass。修:
BufWriter逐行写 canonical 文本;解析结果Vec<String>直接传递或缓存解析形态,避免读回重解析。3. classify_rules → rebuild 双重插入
classify_rules先建HashMap<String, IpAddr>/HashSet<String>,AdBlockEngine::rebuild再逐条 insert 进 trie:每个域名每次 reload 被复制/哈希两遍。修:从 parse 输出直接构建 trie,跳过中间 HashMap/HashSet。
4.
snapshot()在 enabled 检查之前mhost-dns/src/adblock.rs:232-241:adblock 关闭(常见态)时每查询仍付 1 次读锁 + Arc 引用计数。修:把
enabled.load()提到snapshot()之前。验证
cargo test --all-features全绿;rebuild/refresh 路径可加一个分配计数基准(#[global_allocator]counting allocator 或 dhat)证明下降。