performance_test/
performance_test.rs

1use ascii_dag::graph::DAG;
2use std::time::Instant;
3
4fn main() {
5    println!("=== Performance Test: Large DAG ===\n");
6
7    // Create a large graph with 100 nodes and complex structure
8    let mut dag = DAG::new();
9
10    // Create labels that live long enough
11    let labels: Vec<String> = (0..100).map(|i| format!("Node{}", i)).collect();
12    let label_strs: Vec<&str> = labels.iter().map(|s| s.as_str()).collect();
13
14    // Add 100 nodes
15    let start = Instant::now();
16    for i in 0..100 {
17        dag.add_node(i, label_strs[i]);
18    }
19    println!("✓ Added 100 nodes in {:?}", start.elapsed());
20
21    // Add edges to create a complex DAG (each node connects to 2-3 children)
22    let start = Instant::now();
23    for i in 0..80 {
24        dag.add_edge(i, i + 10);
25        dag.add_edge(i, i + 15);
26        if i % 2 == 0 {
27            dag.add_edge(i, i + 20);
28        }
29    }
30    println!("✓ Added ~240 edges in {:?}", start.elapsed());
31
32    // Render the graph (this is where optimizations matter most)
33    let start = Instant::now();
34    let output = dag.render();
35    let render_time = start.elapsed();
36
37    println!("✓ Rendered DAG in {:?}", render_time);
38    println!("\nOutput summary:");
39    println!("  - {} lines", output.lines().count());
40    println!("  - {} characters", output.len());
41
42    // Test auto-created node promotion performance
43    let start = Instant::now();
44    let mut dag2 = DAG::new();
45    let promoted_labels: Vec<String> = (50..100).map(|i| format!("Promoted{}", i)).collect();
46    let promoted_strs: Vec<&str> = promoted_labels.iter().map(|s| s.as_str()).collect();
47
48    for i in 0..50 {
49        dag2.add_edge(i, i + 50); // Auto-creates node i+50
50    }
51    for i in 50..100 {
52        dag2.add_node(i, promoted_strs[i - 50]); // Promotes placeholder
53    }
54    println!(
55        "\n✓ Promoted 50 auto-created nodes in {:?}",
56        start.elapsed()
57    );
58
59    println!("\n=== Optimizations Applied ===");
60    println!("• O(1) HashMap lookups for id→index (was O(n) scan)");
61    println!("• O(1) HashSet for auto_created tracking (was O(n) Vec)");
62    println!("• Cached node widths (avoids repeated chars().count())");
63    println!("• Eliminated level cloning in Sugiyama passes");
64}