Last Updated: January 2026 Parser Version: 0.5.1 Benchmark Methodology: Multiple runs with warmup, statistical analysis using
hyperfine,perf, and/usr/bin/time
Note
Documentation was written using claude
- Executive Summary
- Test Environment
- Benchmark Results
- Scaling Analysis
- Output Characteristics
- Performance Bottlenecks
- Optimization Recommendations
- Benchmarking Guide
- Comparison with Other Tools
- Known Limitations
| Metric | Value |
|---|---|
| Maximum Throughput | 2,054 files/sec (483K LOC/sec) |
| Scalability | Sub-linear (3.76x faster per-file at enterprise scale) |
| Memory Efficiency | 79 KB/file at scale (improves with size) |
| CPU Utilization | 7.89 cores (65.8% efficiency with 12 threads) |
| Largest Tested | 28,551 files, 6.7M LOC in 13.9s |
✅ Exceptional scalability - Performance improves with codebase size
✅ Memory efficient - Linear memory growth, sub-linear per-file cost
✅ Production ready - Handles enterprise codebases (28K+ files)
✅ Consistent performance - Low variance across runs
CPU: AMD Ryzen 5 5600X (12) @ 4.65 GHz
RAM: 16 GB DDR4
Storage: NVMe SSD
OS: Arch Linux
Kernel: Linux 6.12.69-1-lts
Rust: rustc 1.93.0 (254b59607 2026-01-19)
Parser: tree-sitter(0.20) based
Threads: Rayon(1.8) work-stealing thread pool
- hyperfine v1.20.0 - Statistical timing with warmup
- perf stat v6.19.1 - CPU performance counters
- /usr/bin/time - Detailed resource usage
- Project: DLP GUI Wrapper
- Language: Python 3.14.2
| Metric | Value |
|---|---|
| Execution Time | 16.6 ms ± 0.9 ms |
| Throughput | 542 files/sec |
| Processing Rate | 198K LOC/sec |
| Peak Memory | 12.3 MB |
| CPU Utilization | 266% (2.66 cores) |
Instructions: 390 million
Cycles: 157 million
IPC: 2.49
Branch Prediction: 98.79%
Stalled Cycles: 9.85%
Page Faults (minor): 2,355
File System Outputs: 2,472
Context Switches: 35 voluntary, 2 involuntary
| File | Size |
|---|---|
| kb.json | ~1.0 MB |
| kb_index.json | ~21 KB |
| kb_summary.json | ~1.5 KB |
| kb_call_graph.json | ~196 KB |
| Total | ~1.3 MB |
Project: gin-gonic (Go web framework) Language: Go
| Metric | Value |
|---|---|
| Execution Time | 93.7 ms ± 8.0 ms |
| Throughput | 1,024 files/sec |
| Processing Rate | 242K LOC/sec |
| Peak Memory | 31 MB |
| CPU Utilization | 199% (2.0 cores) |
Instructions: 2.23 billion
Cycles: 833 million
IPC: 2.67
Branch Prediction: 99.01%
Stalled Cycles: 9.27%
Page Faults (minor): 7,047
File System Outputs: 16,384
Context Switches: 221 voluntary, 6 involuntary
| File | Size |
|---|---|
| kb.json | ~6.4 MB |
| kb_index.json | ~428 KB |
| kb_summary.json | ~4.8 KB |
| kb_call_graph.json | ~1.4 MB |
| Total | ~8.1 MB |
Project: Django (Python web framework) Language: Python
| Metric | Value |
|---|---|
| Execution Time | 2.01 s ± 0.03 s |
| Throughput | 1,429 files/sec |
| Processing Rate | 249K LOC/sec |
| Peak Memory | 581 MB |
| CPU Utilization | 304% (3.04 cores) |
| Metric | Value |
|---|---|
| Execution Time | 1.90 s ± 0.04 s |
| Throughput | 1,513 files/sec |
| Processing Rate | 264K LOC/sec |
| Peak Memory | 608 MB |
| CPU Utilization | 510% (5.10 cores) |
Instructions: 59.3 billion
Cycles: 38.9 billion
IPC: 1.53
Branch Prediction: 98.36%
Stalled Cycles: 13.08%
Page Faults (minor): 87,041
File System Outputs: 633,792
Context Switches: 7,311 voluntary, 2,733 involuntary
| File | Size |
|---|---|
| kb.json | ~230 MB |
| kb_index.json | ~50 MB |
| kb_summary.json | ~25 KB |
| kb_call_graph.json | ~30 MB |
| Total | ~310 MB |
Project: OpenStack (with all submodules) Language: Python Configuration: 12 threads
| Metric | Value |
|---|---|
| Execution Time | 13.90 s |
| Throughput | 2,054 files/sec |
| Processing Rate | 483K LOC/sec |
| Peak Memory | 2.21 GB |
| CPU Utilization | 789% (7.89 cores) |
Instructions: 693.4 billion
Cycles: 447.8 billion
IPC: 1.55
Branch Prediction: 98.65%
Stalled Cycles: 11.71%
Page Faults (minor): 319,627
File System Outputs: 2,086,360
Context Switches: 24,041 voluntary, 10,658 involuntary
| File | Size |
|---|---|
| kb.json | ~750 MB |
| kb_index.json | ~180 MB |
| kb_summary.json | ~500 KB |
| kb_call_graph.json | ~88 MB |
| Total | ~1,019 MB (1.0 GB) |
| Files | LOC | Time | Files/sec | Time/File | Time/1K LOC |
|---|---|---|---|---|---|
| 9 | 3,287 | 16.6 ms | 542 | 1.84 ms | 5.05 ms |
| 96 | 22,676 | 93.7 ms | 1,024 | 0.98 ms | 4.13 ms |
| 2,874 | 500,734 | 1,940 ms | 1,481 | 0.67 ms | 3.87 ms |
| 28,551 | 6,709,403 | 13,900 ms | 2,054 | 0.49 ms | 2.07 ms |
Key Insight: Processing time per file decreases by 3.76x from small to enterprise scale. This is sub-linear scaling - the parser becomes more efficient as projects grow.
| Files | Peak Memory | Memory/File | Memory/1K LOC |
|---|---|---|---|
| 9 | 12.3 MB | 1,367 KB | 3,743 KB |
| 96 | 31 MB | 323 KB | 1,367 KB |
| 2,874 | 581 MB | 202 KB | 1,160 KB |
| 28,551 | 2,210 MB | 79 KB | 329 KB |
Key Insight: Memory per file drops 17.3x from small to enterprise scale due to shared data structures and graph deduplication.
| Threads | Time | Speedup | Efficiency | Cores Used |
|---|---|---|---|---|
| 4* | ~2.5s | 2.8x | 70% | 2.8 |
| 6 | 2.01s | 3.5x | 58% | 3.0 |
| 12 | 1.90s | 3.7x | 31% | 5.1 |
*Extrapolated
Key Insight: Optimal thread count is 6-8 threads for most projects. Beyond 8 threads, lock contention reduces efficiency.
| Threads | Time* | Speedup | Efficiency | Cores Used |
|---|---|---|---|---|
| 6 | ~18s | 3.9x | 65% | 3.9 |
| 12 | 13.9s | 5.0x | 42% | 7.9 |
*6-thread value extrapolated
Key Insight: At enterprise scale, 12 threads is optimal - larger workloads justify the thread overhead.
| Project | Files | LOC | Total Output | Output/File | Output/1K LOC |
|---|---|---|---|---|---|
| Small | 9 | 3,287 | 1.3 MB | 144 KB | 395 KB |
| Medium | 96 | 22,676 | 8.1 MB | 84 KB | 357 KB |
| Large | 2,874 | 500,734 | 310 MB | 108 KB | 619 KB |
| Enterprise | 28,551 | 6,709,403 | 1,019 MB | 36 KB | 152 KB |
Key Insight: Output size per file drops 4x at enterprise scale, indicating efficient graph representation and deduplication.
kb.json (750 MB) ████████████████████████░░ 73.6%
├─ Structure data ████████████████░░░░░░░░░░ 50.0%
├─ Call graph inline ████████░░░░░░░░░░░░░░░░░░ 15.0%
└─ Metadata ████░░░░░░░░░░░░░░░░░░░░░░ 8.6%
kb_index.json (180 MB) ██████░░░░░░░░░░░░░░░░░░░░ 17.7%
├─ Function indices ████░░░░░░░░░░░░░░░░░░░░░░ 10.0%
├─ Type indices ██░░░░░░░░░░░░░░░░░░░░░░░░ 5.0%
└─ Call graph indices ██░░░░░░░░░░░░░░░░░░░░░░░░ 2.7%
kb_call_graph.json (88 MB) ███░░░░░░░░░░░░░░░░░░░░░░░ 8.6%
├─ Nodes ██░░░░░░░░░░░░░░░░░░░░░░░░ 4.0%
└─ Edges █░░░░░░░░░░░░░░░░░░░░░░░░░ 4.6%
kb_summary.json (500 KB) ░░░░░░░░░░░░░░░░░░░░░░░░░░ 0.05%
The parser uses uncompressed JSON for maximum compatibility with embedding pipelines and vector databases. While this increases output size, it provides:
- ✅ Direct parsing - No decompression step needed
- ✅ Streaming support - Can process incrementally
- ✅ Text-based - Easy debugging and validation
- ✅ Standard format - Works with all JSON tooling
Trade-off: ~4-5x larger output vs compressed, but faster embedding generation.
┌─────────────────────────────────────────────────────┐
│ Phase | Time | % Total | Parallel │
├─────────────────────────────────────────────────────┤
│ File Discovery | 0.20s | 1.4% | ✓ │
│ Language Detection | 0.10s | 0.7% | ✓ │
│ Parser (tree-sitter) | 11.50s | 82.7% | ✓✓✓ │
│ KB Builder (graphs) | 1.20s | 8.6% | ✓ │
│ Serializer (JSON) | 0.90s | 6.5% | ✗ │
└─────────────────────────────────────────────────────┘
Legend: ✓✓✓ = Excellent parallelization
✓ = Good parallelization
✗ = Sequential (bottleneck)
Current Implementation:
- Single-threaded write
- Unbuffered I/O (2,086,360 syscalls for enterprise project)
- 6.5% of total execution time
Impact Analysis:
| Project | Syscalls | Write Time | % of Total |
|---|---|---|---|
| Small | 2,472 | ~5ms | 3.0% |
| Medium | 16,384 | ~15ms | 1.6% |
| Large | 633,792 | ~100ms | 5.5% |
| Enterprise | 2,086,360 | ~900ms | 6.5% |
Observation: As project size increases, serialization becomes a larger bottleneck (3% → 6.5%).
Evidence (12 threads on enterprise project):
- Involuntary context switches: 10,658 (vs 133 for 6 threads)
- IPC degradation: 2.29 → 1.53 (66% efficiency drop)
- Stalled cycles: 10.53% → 11.71%
Root Cause: Multiple threads updating shared call graph structure with mutex locks.
# Install tools
# Instal hyperfine based on you distro/OS
sudo pacman -S time hyperfine perf
# Single run with detailed metrics
/usr/bin/time -v eulix_parser -r /path/to/project -o output.json -t 12
# Statistical analysis (10 runs with warmup)
hyperfine -w 2 'eulix_parser -r /path/to/project -o output.json -t 12'
# CPU performance counters
perf stat eulix_parser -r /path/to/project -o output.json -t 12#!/bin/bash
for threads in 1 2 4 6 8 12 16; do
echo "Testing with $threads threads..."
hyperfine -w 2 "eulix_parser -r /path/to/project -o out.json -t $threads" \
--export-json "results_${threads}t.json"
done# Track memory over time
/usr/bin/time -v eulix_parser -r . -o out.json -t 12 2>&1 | \
grep -E "Maximum resident|Minor|Major"
# Detailed memory analysis (requires valgrind)
valgrind --tool=massif eulix_parser -r . -o out.json -t 6Good Performance Indicators:
- ✅ Processing rate > 100K LOC/sec
- ✅ CPU utilization > 300% (3+ cores)
- ✅ Memory < 500 KB per file
- ✅ Branch prediction > 95%
- ✅ IPC > 1.5
Performance Issues:
⚠️ High involuntary context switches (>5,000)⚠️ Low IPC (<1.2)⚠️ Major page faults (>0)⚠️ CPU utilization < 200%
-
Call Graph Limit: Processing stops at 20,000 files(hard coded to keep things simple) to prevent memory exhaustion
- Affects projects larger than OpenStack
- Can be increased with more RAM
-
Single-threaded Serialization: Output writing is sequential
- Becomes bottleneck at enterprise scale (6.5% of time)
- Fixable with buffered I/O
-
Diminishing Thread Returns: >8 threads show minimal improvement on small/medium projects
- Lock contention increases
- Only beneficial for enterprise scale
-
Uncompressed JSON: Large output files (1 GB for 28K files)
- Intentional for embedding pipeline compatibility
- 4-5x larger than compressed
| Project Size | Min RAM | Recommended RAM | Min Cores | Recommended Cores |
|---|---|---|---|---|
| < 100 files | 512 MB | 1 GB | 2 | 4 |
| 100-1,000 files | 1 GB | 2 GB | 4 | 6 |
| 1,000-5,000 files | 2 GB | 4 GB | 4 | 8 |
| 5,000-30,000 files | 4 GB | 8 GB | 6 | 12 |
- IPC: Instructions Per Cycle - CPU efficiency metric
- Syscall: System call - request to OS kernel
- Page Fault: Memory access requiring disk I/O
- Context Switch: Thread/process switching overhead
- Branch Prediction: CPU guessing next instruction
All benchmarks can be reproduced using the commands in the Benchmarking Guide. Results may vary based on hardware, system load, and file system cache state.
To contribute benchmark results:
- Run the full benchmark suite
- Include hardware specs
- Note any system-specific configurations
- Submit as PR with results in this format
End of Benchmark Report