performance_test/
performance_test.rs1use std::time::Instant;
6use html_translation_lib::pipeline::{
7 TextCollector, OptimizedTextCollector, ConcurrentBatchProcessor,
8 BatchConfig, Priority
9};
10use html_translation_lib::storage::{GlobalMemoryManager, SmartCacheManager};
11use html5ever::parse_document;
12use html5ever::tendril::TendrilSink;
13use markup5ever_rcdom::RcDom;
14use std::sync::Arc;
15
16fn parse_html(html: &str) -> RcDom {
17 parse_document(RcDom::default(), Default::default())
18 .from_utf8()
19 .read_from(&mut html.as_bytes())
20 .unwrap()
21}
22
23fn generate_large_html() -> String {
24 let mut html = String::from(r#"
25 <html>
26 <head>
27 <title>Performance Test Page</title>
28 <meta name="description" content="A test page for performance benchmarking">
29 </head>
30 <body>
31 "#);
32
33 for i in 0..1000 {
35 html.push_str(&format!(r#"
36 <div class="content-section">
37 <h2>Section {}</h2>
38 <p>This is paragraph {} with some content to translate.</p>
39 <img src="image{}.jpg" alt="Description for image {}" title="Tooltip for image {}">
40 <a href="link{}.html" title="Link to page {}">Link {}</a>
41 <input type="text" placeholder="Enter text for field {}" value="Default value {}">
42 </div>
43 "#, i, i, i, i, i, i, i, i, i, i));
44 }
45
46 html.push_str("</body></html>");
47 html
48}
49
50#[tokio::main]
51async fn main() -> Result<(), Box<dyn std::error::Error>> {
52 println!("🚀 HTML翻译库性能测试\n");
53
54 let large_html = generate_large_html();
55 let dom = parse_html(&large_html);
56
57 println!("📊 测试数据:");
58 println!(" - HTML大小: {} KB", large_html.len() / 1024);
59 println!(" - 包含 ~5000 个文本元素\n");
60
61 println!("🔍 DOM遍历性能对比:");
63
64 let start = Instant::now();
66 let original_collector = TextCollector::new();
67 let original_items = original_collector.collect_from_dom(&dom)?;
68 let original_time = start.elapsed();
69 println!(" - 原始递归收集器: {}ms, 收集到 {} 项",
70 original_time.as_millis(), original_items.len());
71
72 let start = Instant::now();
74 let mut optimized_collector = OptimizedTextCollector::new();
75 let optimized_items = optimized_collector.collect_from_dom_optimized(&dom)?;
76 let optimized_time = start.elapsed();
77 println!(" - 优化迭代收集器: {}ms, 收集到 {} 项",
78 optimized_time.as_millis(), optimized_items.len());
79
80 let speedup = original_time.as_millis() as f64 / optimized_time.as_millis() as f64;
81 println!(" ✨ 性能提升: {:.2}x 倍速\n", speedup);
82
83 println!("💾 内存管理优化:");
85 let memory_manager = Arc::new(GlobalMemoryManager::new());
86
87 let start = Instant::now();
89 let mut test_strings = Vec::new();
90 for i in 0..1000 {
91 let s = memory_manager.acquire_string(50);
92 test_strings.push(format!("Test string {}", i));
93 }
94
95 for s in test_strings {
96 memory_manager.release_string(s);
97 }
98 let pool_time = start.elapsed();
99
100 let (pool_stats, _) = memory_manager.get_pool_stats();
102 println!(" - 字符串池操作: {}ms", pool_time.as_millis());
103 println!(" - 池大小: 小型={}, 大型={}, 总容量={}KB",
104 pool_stats.small_pool_size,
105 pool_stats.large_pool_size,
106 pool_stats.total_capacity / 1024);
107
108 println!("\n🧠 智能缓存性能:");
110 use html_translation_lib::config::TranslationConfig;
111
112 let config = TranslationConfig::new()
113 .target_language("zh")
114 .api_url("http://example.com/translate");
115
116 let mut cache_manager = SmartCacheManager::new(&config).await?;
117
118 let start = Instant::now();
119
120 for i in 0..500 {
122 let key = format!("text_{}", i % 100); let value = format!("translation_{}", i);
124 cache_manager.set(&key, value).await?;
125 }
126
127 let mut hits = 0;
129 for i in 0..100 {
130 let key = format!("text_{}", i);
131 if cache_manager.get(&key).await?.is_some() {
132 hits += 1;
133 }
134 }
135
136 let cache_time = start.elapsed();
137 let cache_stats = cache_manager.stats();
138
139 println!(" - 缓存操作时间: {}ms", cache_time.as_millis());
140 println!(" - 缓存命中数: {} / 100", hits);
141 println!(" - L1命中率: {:.1}%", cache_stats.l1_hit_rate() * 100.0);
142 println!(" - 总命中率: {:.1}%", cache_stats.hit_rate() * 100.0);
143
144 println!("\n⚡ 并发批处理性能:");
146 let batch_config = BatchConfig {
147 batch_size: 20,
148 max_concurrency: 4,
149 timeout_duration: std::time::Duration::from_secs(10),
150 ..Default::default()
151 };
152
153 let batch_processor = ConcurrentBatchProcessor::new(
154 batch_config,
155 Arc::clone(&memory_manager)
156 );
157
158 let test_texts: Vec<String> = (0..200)
160 .map(|i| format!("Test text number {}", i))
161 .collect();
162
163 let start = Instant::now();
164
165 let mut task_ids = Vec::new();
167 for chunk in test_texts.chunks(50) {
168 let task_id = batch_processor.submit_batch(
169 chunk.to_vec(),
170 Priority::Normal
171 ).await?;
172 task_ids.push(task_id);
173 }
174
175 async fn mock_translate(texts: Vec<String>) -> html_translation_lib::error::TranslationResult<Vec<String>> {
177 tokio::time::sleep(std::time::Duration::from_millis(10)).await;
178 Ok(texts.into_iter().map(|t| format!("翻译_{}", t)).collect())
179 }
180
181 let _results = batch_processor.process_queue(mock_translate).await?;
183 let batch_time = start.elapsed();
184
185 let batch_stats = batch_processor.get_stats().await;
186 let queue_status = batch_processor.get_queue_status();
187
188 println!(" - 批处理总时间: {}ms", batch_time.as_millis());
189 println!(" - 处理成功率: {:.1}%", batch_stats.success_rate() * 100.0);
190 println!(" - 平均处理时间: {}ms", batch_stats.average_processing_time().as_millis());
191 println!(" - 吞吐量: {:.1} 任务/秒", batch_stats.throughput());
192 println!(" - 队列剩余: {} 任务", queue_status.total_tasks);
193
194 println!("\n📈 性能优化总结:");
196 println!(" ✅ DOM遍历优化: {:.1}x 性能提升", speedup);
197 println!(" ✅ 内存池管理: 减少 GC 压力");
198 println!(" ✅ 智能缓存: {:.1}% 命中率", cache_stats.hit_rate() * 100.0);
199 println!(" ✅ 并发批处理: {:.1}% 成功率", batch_stats.success_rate() * 100.0);
200 println!("\n🎉 所有性能优化测试完成!");
201
202 Ok(())
203}