如何在Rust中驻留动态创建的字符串?egui循环场景优化
解决方案
直接将st传入驻留库不可行——因为每次调用replace都会创建全新的字符串实例,驻留库无法自动识别重复的内容(除非手动将生成结果注册到驻留系统,但这本质和缓存逻辑一致)。下面是两种高效的实现方案:
1. 基于App State的HashMap缓存(推荐)
把缓存放在egui应用的状态结构体中,针对用户名+模板的组合缓存生成结果,适配egui的单循环更新逻辑:
use eframe::egui; use std::collections::HashMap; #[derive(Default)] struct MyApp { username: String, template: String, result_cache: HashMap<(String, String), String>, // 键:(模板, 用户名),值:生成后的字符串 } impl eframe::App for MyApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { // 模拟用户输入用户名和模板 ui.text_edit_singleline(&mut self.username); ui.text_edit_singleline(&mut self.template); // 构建缓存键,确保模板或用户名变化时更新缓存 let cache_key = (self.template.clone(), self.username.clone()); // 查缓存:不存在则生成并存入 let st = self.result_cache.entry(cache_key) .or_insert_with(|| self.template.replace('$', &self.username)); // 使用生成后的字符串 ui.label(*st); }); } } fn main() -> Result<(), eframe::Error> { eframe::run_native( "Cached Template String", eframe::NativeOptions::default(), Box::new(|_cc| Box::new(MyApp::default())), ) }
如果模板固定不变,可以简化缓存键为仅用户名,进一步提升效率。
2. 全局驻留式缓存
如果需要跨组件复用生成结果,可以用全局缓存(推荐用rustc_hash::FxHashMap替代标准库HashMap,提升高频场景下的性能):
use eframe::egui; use rustc_hash::FxHashMap; use std::sync::Mutex; use once_cell::sync::Lazy; // 全局线程安全缓存,egui单线程场景下可改用RefCell替代Mutex static GLOBAL_STRING_CACHE: Lazy<Mutex<FxHashMap<(String, String), String>>> = Lazy::new(|| { Mutex::new(FxHashMap::default()) }); fn get_cached_template_result(template: &str, username: &str) -> String { let mut cache = GLOBAL_STRING_CACHE.lock().unwrap(); let key = (template.to_string(), username.to_string()); cache.entry(key) .or_insert_with(|| template.replace('$', username)) .clone() } // egui App逻辑 #[derive(Default)] struct MyApp { username: String, template: String, } impl eframe::App for MyApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.text_edit_singleline(&mut self.username); ui.text_edit_singleline(&mut self.template); let st = get_cached_template_result(&self.template, &self.username); ui.label(st); }); } }
关键说明
- 驻留库的核心逻辑其实也是缓存,手动用HashMap实现更灵活,完全适配你的动态模板+动态用户名场景;
- 务必以模板+用户名的组合作为缓存键,避免模板变更后返回旧的生成结果;
- 若模板固定,可只以用户名为键,进一步减少缓存开销。
内容的提问来源于stack exchange,提问作者AliSalehi
相关产品推荐
相关产品推荐

