|
| 1 | +/// Performance test for large schema processing |
| 2 | +/// Measures the time to create a Template with a large schema |
| 3 | +
|
| 4 | +#[cfg(not(debug_assertions))] |
| 5 | +use std::time::Instant; |
| 6 | + |
| 7 | +/// Generate a large schema with the specified number of keys |
| 8 | +#[cfg(not(debug_assertions))] |
| 9 | +fn generate_large_schema(num_keys: usize) -> serde_json::Value { |
| 10 | + let mut data = serde_json::Map::new(); |
| 11 | + |
| 12 | + for i in 0..num_keys { |
| 13 | + let key = format!("key_{}", i); |
| 14 | + let value = serde_json::json!({ |
| 15 | + "id": i, |
| 16 | + "name": format!("Item {}", i), |
| 17 | + "description": format!("This is a detailed description for item number {} with some extra text to make it larger", i), |
| 18 | + "tags": ["tag1", "tag2", "tag3"], |
| 19 | + "metadata": { |
| 20 | + "created": "2024-01-01", |
| 21 | + "updated": "2024-12-31", |
| 22 | + "author": format!("author_{}", i % 100), |
| 23 | + "version": format!("1.{}.0", i % 10) |
| 24 | + } |
| 25 | + }); |
| 26 | + data.insert(key, value); |
| 27 | + } |
| 28 | + |
| 29 | + serde_json::json!({ |
| 30 | + "config": { |
| 31 | + "infinite_loop_max_bifs": 555000, |
| 32 | + "comments": "keep", |
| 33 | + "errors": "hide" |
| 34 | + }, |
| 35 | + "inherit": { |
| 36 | + "snippets": {}, |
| 37 | + "declare": { |
| 38 | + "any": "*" |
| 39 | + }, |
| 40 | + "params": {}, |
| 41 | + "locale": { |
| 42 | + "current": "en", |
| 43 | + "trans": {} |
| 44 | + } |
| 45 | + }, |
| 46 | + "data": data |
| 47 | + }) |
| 48 | +} |
| 49 | + |
| 50 | +#[cfg(not(debug_assertions))] |
| 51 | +#[test] |
| 52 | +fn test_large_schema_performance() { |
| 53 | + let schema_sizes = [100, 500, 1000, 2000]; |
| 54 | + let iterations = 10; |
| 55 | + |
| 56 | + println!("\n=== Large Schema Performance Test ===\n"); |
| 57 | + println!("{:<10} {:<15} {:<15} {:<15}", "Keys", "Size (KB)", "Time (ms)", "Per key (µs)"); |
| 58 | + println!("{}", "-".repeat(55)); |
| 59 | + |
| 60 | + for num_keys in schema_sizes { |
| 61 | + let schema = generate_large_schema(num_keys); |
| 62 | + let schema_size = serde_json::to_string(&schema).unwrap().len(); |
| 63 | + |
| 64 | + // Warmup |
| 65 | + let schema_clone = schema.clone(); |
| 66 | + let _ = neutralts::Template::from_file_value("tests/obj.ntpl", schema_clone); |
| 67 | + |
| 68 | + // Measure |
| 69 | + let mut total_time = 0u128; |
| 70 | + for _ in 0..iterations { |
| 71 | + let schema_clone = schema.clone(); |
| 72 | + let start = Instant::now(); |
| 73 | + let result = neutralts::Template::from_file_value("tests/obj.ntpl", schema_clone); |
| 74 | + let elapsed = start.elapsed().as_nanos(); |
| 75 | + |
| 76 | + assert!(result.is_ok(), "Template creation failed"); |
| 77 | + total_time += elapsed; |
| 78 | + } |
| 79 | + |
| 80 | + let avg_time_ns = total_time / iterations as u128; |
| 81 | + let avg_time_ms = avg_time_ns as f64 / 1_000_000.0; |
| 82 | + let per_key_us = (avg_time_ns as f64 / num_keys as f64) / 1000.0; |
| 83 | + |
| 84 | + println!( |
| 85 | + "{:<10} {:<15.1} {:<15.2} {:<15.2}", |
| 86 | + num_keys, |
| 87 | + schema_size as f64 / 1024.0, |
| 88 | + avg_time_ms, |
| 89 | + per_key_us |
| 90 | + ); |
| 91 | + } |
| 92 | + |
| 93 | + println!(); |
| 94 | +} |
| 95 | + |
| 96 | +#[cfg(not(debug_assertions))] |
| 97 | +#[test] |
| 98 | +fn test_schema_merge_performance() { |
| 99 | + use neutralts::Template; |
| 100 | + |
| 101 | + let num_keys = 1000; |
| 102 | + let schema = generate_large_schema(num_keys); |
| 103 | + let schema_str = serde_json::to_string(&schema).unwrap(); |
| 104 | + |
| 105 | + println!("\n=== Schema Merge Performance Test ===\n"); |
| 106 | + println!("Schema size: {} bytes ({:.1} KB)", schema_str.len(), schema_str.len() as f64 / 1024.0); |
| 107 | + |
| 108 | + // Test merge_schema_str (parses JSON) |
| 109 | + let iterations = 20; |
| 110 | + let mut total_time = 0u128; |
| 111 | + |
| 112 | + for _ in 0..iterations { |
| 113 | + let mut template = Template::new().unwrap(); |
| 114 | + let start = Instant::now(); |
| 115 | + template.merge_schema_str(&schema_str).unwrap(); |
| 116 | + total_time += start.elapsed().as_nanos(); |
| 117 | + } |
| 118 | + |
| 119 | + let avg_time_ms = (total_time / iterations as u128) as f64 / 1_000_000.0; |
| 120 | + println!("merge_schema_str avg time: {:.2} ms", avg_time_ms); |
| 121 | + |
| 122 | + // Test merge_schema_value (already parsed) |
| 123 | + let mut total_time = 0u128; |
| 124 | + |
| 125 | + for _ in 0..iterations { |
| 126 | + let mut template = Template::new().unwrap(); |
| 127 | + let schema_clone = schema.clone(); |
| 128 | + let start = Instant::now(); |
| 129 | + template.merge_schema_value(schema_clone); |
| 130 | + total_time += start.elapsed().as_nanos(); |
| 131 | + } |
| 132 | + |
| 133 | + let avg_time_ms = (total_time / iterations as u128) as f64 / 1_000_000.0; |
| 134 | + println!("merge_schema_value avg time: {:.2} ms", avg_time_ms); |
| 135 | + |
| 136 | + println!(); |
| 137 | +} |
0 commit comments