caching_performance/
caching_performance.rs1use tron::{TemplateCache, CacheConfig, TemplateLoader, LoaderConfig, TronTemplate};
7use std::time::{Duration, Instant};
8
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10 println!("=== Tron Template Caching and Performance Example ===\n");
11
12 demonstrate_basic_caching()?;
14
15 demonstrate_cache_performance()?;
17
18 demonstrate_cache_configuration()?;
20
21 demonstrate_loader_caching()?;
23
24 demonstrate_cache_monitoring()?;
26
27 Ok(())
28}
29
30fn demonstrate_basic_caching() -> Result<(), Box<dyn std::error::Error>> {
31 println!("1. Basic Template Caching:");
32
33 let cache = TemplateCache::new();
34
35 let templates = vec![
37 ("function", TronTemplate::new("fn @[name]@(@[params]@) -> @[return_type]@ { @[body]@ }")?),
38 ("struct", TronTemplate::new("struct @[name]@ { @[fields]@ }")?),
39 ("impl", TronTemplate::new("impl @[name]@ { @[methods]@ }")?),
40 ];
41
42 for (name, template) in &templates {
44 cache.insert_template(template.clone())?;
45 println!(" - Cached template: {}", name);
46 }
47
48 println!(" - Cache size: {}", cache.size());
49
50 if let Some(_template) = cache.get_by_content("fn @[name]@(@[params]@) -> @[return_type]@ { @[body]@ }") {
52 println!(" - Successfully retrieved function template from cache");
53 }
54
55 println!();
56 Ok(())
57}
58
59fn demonstrate_cache_performance() -> Result<(), Box<dyn std::error::Error>> {
60 println!("2. Cache Performance Comparison:");
61
62 let template_content = "fn @[name]@(@[params]@) -> @[return_type]@ {\n @[body]@\n}";
63 let iterations = 1000;
64
65 let start = Instant::now();
67 for _ in 0..iterations {
68 let _template = TronTemplate::new(template_content)?;
69 }
70 let no_cache_duration = start.elapsed();
71
72 let cache = TemplateCache::new();
74 let template = TronTemplate::new(template_content)?;
75 cache.insert_template(template)?;
76
77 let start = Instant::now();
78 for _ in 0..iterations {
79 let _cached_template = cache.get_by_content(template_content);
80 }
81 let cache_duration = start.elapsed();
82
83 println!(" - Without caching: {:?} ({} iterations)", no_cache_duration, iterations);
84 println!(" - With caching: {:?} ({} iterations)", cache_duration, iterations);
85 println!(" - Performance improvement: {:.2}x faster",
86 no_cache_duration.as_nanos() as f64 / cache_duration.as_nanos() as f64);
87
88 println!();
89 Ok(())
90}
91
92fn demonstrate_cache_configuration() -> Result<(), Box<dyn std::error::Error>> {
93 println!("3. Cache Configuration and Tuning:");
94
95 let config = CacheConfig {
97 max_size: 50, max_age: Some(Duration::from_secs(300)), track_file_changes: true, enable_stats: true, };
102
103 let cache = TemplateCache::with_config(config);
104
105 println!(" - Max cache size: 50 templates");
106 println!(" - Max entry age: 5 minutes");
107 println!(" - File change tracking: enabled");
108 println!(" - Statistics tracking: enabled");
109
110 for i in 0..55 {
112 let template = TronTemplate::new(&format!("Template {} content @[placeholder]@", i))?;
113 cache.insert_template(template)?;
114 }
115
116 println!(" - Added 55 templates, cache size: {} (evicted {})",
117 cache.size(), 55 - cache.size());
118
119 if let Some(stats) = cache.stats() {
121 println!(" - Cache hits: {}", stats.hits);
122 println!(" - Cache misses: {}", stats.misses);
123 println!(" - Evictions: {}", stats.evictions);
124 }
125
126 println!();
127 Ok(())
128}
129
130fn demonstrate_loader_caching() -> Result<(), Box<dyn std::error::Error>> {
131 println!("4. Advanced Loader with Caching:");
132
133 let loader_config = LoaderConfig {
135 enable_caching: true,
136 cache_config: CacheConfig {
137 max_size: 100,
138 max_age: Some(Duration::from_secs(600)), track_file_changes: true,
140 enable_stats: true,
141 },
142 ..LoaderConfig::default()
143 };
144
145 let mut loader = TemplateLoader::with_config(loader_config);
146
147 println!(" - Loading templates from directory (with caching)...");
149 let start = Instant::now();
150 let templates = loader.load_from_directory("templates")?;
151 let first_load_time = start.elapsed();
152
153 println!(" - First load: {} templates in {:?}", templates.len(), first_load_time);
154 println!(" - Cache size: {}", loader.cache_size());
155
156 let start = Instant::now();
158 let _templates = loader.load_from_directory("templates")?;
159 let cached_load_time = start.elapsed();
160
161 println!(" - Cached load: {:?} ({}x faster)",
162 cached_load_time,
163 first_load_time.as_nanos() / cached_load_time.as_nanos().max(1));
164
165 if let Some(stats) = loader.cache_stats() {
167 println!(" - Cache hit ratio: {:.2}%", stats.hit_ratio() * 100.0);
168 println!(" - Total hits: {}, misses: {}", stats.hits, stats.misses);
169 }
170
171 println!();
172 Ok(())
173}
174
175fn demonstrate_cache_monitoring() -> Result<(), Box<dyn std::error::Error>> {
176 println!("5. Cache Statistics and Monitoring:");
177
178 let cache = TemplateCache::with_config(CacheConfig {
179 enable_stats: true,
180 max_size: 10,
181 ..CacheConfig::default()
182 });
183
184 let templates = vec![
186 "Template A: @[content]@",
187 "Template B: @[data]@",
188 "Template C: @[info]@",
189 "Template D: @[value]@",
190 "Template E: @[result]@",
191 ];
192
193 for template_content in &templates {
195 let template = TronTemplate::new(template_content)?;
196 cache.insert_template(template)?;
197 }
198
199 for _ in 0..10 {
201 let _hit = cache.get_by_content(templates[0]);
203 let _hit = cache.get_by_content(templates[1]);
204
205 let _miss = cache.get_by_content("Nonexistent template @[x]@");
207 }
208
209 for i in 6..15 {
211 let template = TronTemplate::new(&format!("Template {}: @[data]@", i))?;
212 cache.insert_template(template)?;
213 }
214
215 if let Some(stats) = cache.stats() {
217 println!(" - Cache Performance Metrics:");
218 println!(" * Total requests: {}", stats.hits + stats.misses);
219 println!(" * Cache hits: {}", stats.hits);
220 println!(" * Cache misses: {}", stats.misses);
221 println!(" * Hit ratio: {:.2}%", stats.hit_ratio() * 100.0);
222 println!(" * Evictions: {}", stats.evictions);
223 println!(" * Invalidations: {}", stats.invalidations);
224 }
225
226 println!(" - Current cache size: {}", cache.size());
227 println!(" - Cache is empty: {}", cache.is_empty());
228
229 cache.cleanup_expired();
231 println!(" - After cleanup: {} templates", cache.size());
232
233 println!();
234 Ok(())
235}
236
237#[cfg(test)]
238mod tests {
239 use super::*;
240
241 #[test]
242 fn test_cache_performance_benefits() -> Result<(), Box<dyn std::error::Error>> {
243 let cache = TemplateCache::new();
244 let template = TronTemplate::new("Test template @[placeholder]@")?;
245
246 cache.insert_template(template.clone())?;
248
249 let cached = cache.get_by_content("Test template @[placeholder]@");
251 assert!(cached.is_some());
252 assert_eq!(cached.unwrap().content(), template.content());
253
254 Ok(())
255 }
256
257 #[test]
258 fn test_loader_caching_integration() -> Result<(), Box<dyn std::error::Error>> {
259 let config = LoaderConfig {
260 enable_caching: true,
261 ..LoaderConfig::default()
262 };
263
264 let loader = TemplateLoader::with_config(config);
265 assert!(loader.cache_size() == 0);
266
267 assert!(loader.cache_stats().is_some());
269
270 Ok(())
271 }
272}