use std::time::Instant;
use html_translation_lib::pipeline::{
TextCollector, OptimizedTextCollector, ConcurrentBatchProcessor,
BatchConfig, Priority
};
use html_translation_lib::storage::{GlobalMemoryManager, SmartCacheManager};
use html5ever::parse_document;
use html5ever::tendril::TendrilSink;
use markup5ever_rcdom::RcDom;
use std::sync::Arc;
fn parse_html(html: &str) -> RcDom {
parse_document(RcDom::default(), Default::default())
.from_utf8()
.read_from(&mut html.as_bytes())
.unwrap()
}
fn generate_large_html() -> String {
let mut html = String::from(r#"
<html>
<head>
<title>Performance Test Page</title>
<meta name="description" content="A test page for performance benchmarking">
</head>
<body>
"#);
for i in 0..1000 {
html.push_str(&format!(r#"
<div class="content-section">
<h2>Section {}</h2>
<p>This is paragraph {} with some content to translate.</p>
<img src="image{}.jpg" alt="Description for image {}" title="Tooltip for image {}">
<a href="link{}.html" title="Link to page {}">Link {}</a>
<input type="text" placeholder="Enter text for field {}" value="Default value {}">
</div>
"#, i, i, i, i, i, i, i, i, i, i));
}
html.push_str("</body></html>");
html
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🚀 HTML翻译库性能测试\n");
let large_html = generate_large_html();
let dom = parse_html(&large_html);
println!("📊 测试数据:");
println!(" - HTML大小: {} KB", large_html.len() / 1024);
println!(" - 包含 ~5000 个文本元素\n");
println!("🔍 DOM遍历性能对比:");
let start = Instant::now();
let original_collector = TextCollector::new();
let original_items = original_collector.collect_from_dom(&dom)?;
let original_time = start.elapsed();
println!(" - 原始递归收集器: {}ms, 收集到 {} 项",
original_time.as_millis(), original_items.len());
let start = Instant::now();
let mut optimized_collector = OptimizedTextCollector::new();
let optimized_items = optimized_collector.collect_from_dom_optimized(&dom)?;
let optimized_time = start.elapsed();
println!(" - 优化迭代收集器: {}ms, 收集到 {} 项",
optimized_time.as_millis(), optimized_items.len());
let speedup = original_time.as_millis() as f64 / optimized_time.as_millis() as f64;
println!(" ✨ 性能提升: {:.2}x 倍速\n", speedup);
println!("💾 内存管理优化:");
let memory_manager = Arc::new(GlobalMemoryManager::new());
let start = Instant::now();
let mut test_strings = Vec::new();
for i in 0..1000 {
let s = memory_manager.acquire_string(50);
test_strings.push(format!("Test string {}", i));
}
for s in test_strings {
memory_manager.release_string(s);
}
let pool_time = start.elapsed();
let (pool_stats, _) = memory_manager.get_pool_stats();
println!(" - 字符串池操作: {}ms", pool_time.as_millis());
println!(" - 池大小: 小型={}, 大型={}, 总容量={}KB",
pool_stats.small_pool_size,
pool_stats.large_pool_size,
pool_stats.total_capacity / 1024);
println!("\n🧠 智能缓存性能:");
use html_translation_lib::config::TranslationConfig;
let config = TranslationConfig::new()
.target_language("zh")
.api_url("http://example.com/translate");
let mut cache_manager = SmartCacheManager::new(&config).await?;
let start = Instant::now();
for i in 0..500 {
let key = format!("text_{}", i % 100); let value = format!("translation_{}", i);
cache_manager.set(&key, value).await?;
}
let mut hits = 0;
for i in 0..100 {
let key = format!("text_{}", i);
if cache_manager.get(&key).await?.is_some() {
hits += 1;
}
}
let cache_time = start.elapsed();
let cache_stats = cache_manager.stats();
println!(" - 缓存操作时间: {}ms", cache_time.as_millis());
println!(" - 缓存命中数: {} / 100", hits);
println!(" - L1命中率: {:.1}%", cache_stats.l1_hit_rate() * 100.0);
println!(" - 总命中率: {:.1}%", cache_stats.hit_rate() * 100.0);
println!("\n⚡ 并发批处理性能:");
let batch_config = BatchConfig {
batch_size: 20,
max_concurrency: 4,
timeout_duration: std::time::Duration::from_secs(10),
..Default::default()
};
let batch_processor = ConcurrentBatchProcessor::new(
batch_config,
Arc::clone(&memory_manager)
);
let test_texts: Vec<String> = (0..200)
.map(|i| format!("Test text number {}", i))
.collect();
let start = Instant::now();
let mut task_ids = Vec::new();
for chunk in test_texts.chunks(50) {
let task_id = batch_processor.submit_batch(
chunk.to_vec(),
Priority::Normal
).await?;
task_ids.push(task_id);
}
async fn mock_translate(texts: Vec<String>) -> html_translation_lib::error::TranslationResult<Vec<String>> {
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
Ok(texts.into_iter().map(|t| format!("翻译_{}", t)).collect())
}
let _results = batch_processor.process_queue(mock_translate).await?;
let batch_time = start.elapsed();
let batch_stats = batch_processor.get_stats().await;
let queue_status = batch_processor.get_queue_status();
println!(" - 批处理总时间: {}ms", batch_time.as_millis());
println!(" - 处理成功率: {:.1}%", batch_stats.success_rate() * 100.0);
println!(" - 平均处理时间: {}ms", batch_stats.average_processing_time().as_millis());
println!(" - 吞吐量: {:.1} 任务/秒", batch_stats.throughput());
println!(" - 队列剩余: {} 任务", queue_status.total_tasks);
println!("\n📈 性能优化总结:");
println!(" ✅ DOM遍历优化: {:.1}x 性能提升", speedup);
println!(" ✅ 内存池管理: 减少 GC 压力");
println!(" ✅ 智能缓存: {:.1}% 命中率", cache_stats.hit_rate() * 100.0);
println!(" ✅ 并发批处理: {:.1}% 成功率", batch_stats.success_rate() * 100.0);
println!("\n🎉 所有性能优化测试完成!");
Ok(())
}