Skip to content

Commit ca47d03

Browse files
committed
Add performance infos.
1 parent 015c07f commit ca47d03

19 files changed

+4010
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ https://sandbox.dereuromark.de/sandbox/djot
105105
- [Cookbook](docs/cookbook.md) - Common customizations and recipes
106106
- [Architecture](docs/architecture.md) - Internal design
107107
- [Enhancements](docs/enhancements.md) - Fixes beyond the current spec
108+
- [Performance](docs/performance.md) - Benchmarks and performance data
108109

109110
## Security
110111

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This directory contains detailed documentation for djot-php.
99
- [Cookbook](cookbook.md) - Common customizations and recipes
1010
- [Architecture](architecture.md) - Internal design
1111
- [Converters](converters.md) - Markdown/BBCode to Djot conversion
12+
- [Performance](performance.md) - Benchmarks and performance data
1213

1314
## Examples
1415

docs/performance.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Djot-PHP Performance Summary
2+
3+
Performance benchmarks for djot-php compared to other implementations.
4+
5+
**Test Environment:**
6+
- PHP 8.4.15
7+
- Node.js v18.19.1
8+
- Python 3.12.3
9+
- Linux 6.8.0-88-generic
10+
11+
## Quick Reference
12+
13+
| Document Size | PHP Parse | PHP Render | PHP Full | Throughput |
14+
|---------------|-----------|------------|----------|------------|
15+
| 1 KB | 0.35 ms | 0.15 ms | 0.50 ms | ~2.3 MB/s |
16+
| 10 KB | 3.5 ms | 1.5 ms | 5.0 ms | ~2.3 MB/s |
17+
| 50 KB | 18 ms | 8 ms | 26 ms | ~2.2 MB/s |
18+
| 100 KB | 35 ms | 15 ms | 50 ms | ~2.2 MB/s |
19+
| 1 MB | 404 ms | 194 ms | 531 ms | ~1.9 MB/s |
20+
| 10 MB | 4.3 s | 2.6 s | 6.3 s | ~1.6 MB/s |
21+
22+
## Large Document Processing
23+
24+
### 1 MB Document
25+
26+
| Metric | PHP (djot-php) | JS (@djot/djot) |
27+
|-------------------|----------------|-----------------|
28+
| Parse Time | 404 ms | 191 ms |
29+
| Render Time | 194 ms | 51 ms |
30+
| Full Conversion | 531 ms | 248 ms |
31+
| Parse Memory | 38 MB | - |
32+
| Render Memory | 2 MB | - |
33+
| Peak Memory | 44 MB | - |
34+
| Output Size | 1.6 MB | 1.6 MB |
35+
36+
### 10 MB Document
37+
38+
| Metric | PHP (djot-php) | JS (@djot/djot) |
39+
|-------------------|----------------|-----------------|
40+
| Parse Time | 4.3 s | ~1.9 s* |
41+
| Render Time | 2.6 s | ~0.5 s* |
42+
| Full Conversion | 6.3 s | ~2.5 s* |
43+
| Parse Memory | 326 MB | - |
44+
| Render Memory | 18 MB | - |
45+
| Peak Memory | 408 MB | - |
46+
| Output Size | 16 MB | 16 MB |
47+
48+
*JS times estimated from linear scaling
49+
50+
### Memory Scaling
51+
52+
Memory usage scales approximately 40x the input size:
53+
54+
| Input | Parse Mem | Render Mem | Peak Mem | Output |
55+
|---------|-----------|------------|----------|---------|
56+
| 1 MB | 38 MB | 2 MB | 44 MB | 1.6 MB |
57+
| 10 MB | 326 MB | 18 MB | 408 MB | 16 MB |
58+
59+
## Cross-Language Comparison
60+
61+
Benchmarked on medium-sized documents (~56 KB):
62+
63+
| Implementation | Mean Time | Throughput | vs PHP |
64+
|---------------------|-----------|------------|-----------|
65+
| PHP (djot-php) | 18.1 ms | 3.0 MB/s | baseline |
66+
| JS (@djot/djot) | 8.1 ms | 5.2 MB/s | 2.2x faster |
67+
| Python-Markdown | 41.1 ms | 1.0 MB/s | 2.3x slower |
68+
| markdown-it-py | 36.8 ms | 1.2 MB/s | 2.0x slower |
69+
70+
## Document Size Scaling
71+
72+
PHP djot-php scales linearly with document size:
73+
74+
| Size | Input | Mean Time | Throughput |
75+
|---------|-----------|-----------|------------|
76+
| tiny | 1.1 KB | 0.50 ms | 2.3 MB/s |
77+
| small | 11.1 KB | 5.0 ms | 2.3 MB/s |
78+
| medium | 56.1 KB | 26.0 ms | 2.2 MB/s |
79+
| large | 225.5 KB | 105 ms | 2.2 MB/s |
80+
| huge | 1.1 MB | 538 ms | 2.2 MB/s |
81+
82+
## Parse vs Render Breakdown
83+
84+
For a typical document, parsing takes ~75% of total time:
85+
86+
| Phase | Time (medium doc) | Percentage |
87+
|---------|-------------------|------------|
88+
| Parse | 20.8 ms | ~75% |
89+
| Render | 5.1 ms | ~25% |
90+
| **Total** | **25.9 ms** | 100% |
91+
92+
## Profile Performance
93+
94+
Different profiles have similar performance since they filter the same AST:
95+
96+
| Profile | Mean Time | Notes |
97+
|----------|-----------|--------------------------|
98+
| none | 24.9 ms | No filtering |
99+
| full | 32.4 ms | All features enabled |
100+
| article | 35.2 ms | Blog/article content |
101+
| comment | 31.5 ms | User comments |
102+
| minimal | 31.1 ms | Basic text formatting |
103+
104+
## Safe Mode
105+
106+
Safe mode has negligible performance impact:
107+
108+
| Mode | Mean Time |
109+
|----------|-----------|
110+
| Disabled | 27.4 ms |
111+
| Enabled | 25.0 ms |
112+
113+
## Memory Usage
114+
115+
Memory scales approximately linearly with document size:
116+
117+
| Input Size | Peak Memory | Ratio |
118+
|------------|-------------|----------|
119+
| 11 KB | 68 MB | ~6000x |
120+
| 57 KB | 68 MB | ~1200x |
121+
| 226 KB | 70 MB | ~310x |
122+
| 1 MB | ~80 MB | ~80x |
123+
124+
Note: PHP has a base memory overhead. The incremental memory per input byte is approximately 30-45x.
125+
126+
## Content Type Performance
127+
128+
Different content types have varying performance characteristics:
129+
130+
| Content Type | Size | Mean Time | Throughput | Notes |
131+
|----------------|---------|-----------|------------|---------------------------|
132+
| code_heavy | 5.9 KB | 0.66 ms | 9.0 MB/s | Fastest - simple parsing |
133+
| tables | 9.4 KB | 3.9 ms | 2.4 MB/s | Average |
134+
| nested_lists | 5.7 KB | 2.6 ms | 2.2 MB/s | Average |
135+
| complex | 9.1 KB | 6.8 ms | 1.3 MB/s | Many features |
136+
| inline_heavy | 15.1 KB | 11.5 ms | 1.3 MB/s | Many inline elements |
137+
138+
Code-heavy documents are fastest because code blocks require minimal parsing.
139+
140+
## Stress Test Results
141+
142+
All stress tests pass successfully:
143+
144+
| Scenario | Input Size | Mean Time | Status |
145+
|-----------------|------------|-----------|--------|
146+
| deep_nesting | 3.5 KB | 1.4 ms | PASS |
147+
| pathological | 62.6 KB | 22.0 ms | PASS |
148+
| many_paragraphs | 556 KB | 280 ms | PASS |
149+
| huge_table | 121 KB | 45 ms | PASS |
150+
| inline_heavy | 198 KB | 95 ms | PASS |
151+
| memory_pressure | 2 MB | 1.1 s | PASS |
152+
153+
## Running Benchmarks
154+
155+
```bash
156+
# Quick PHP benchmark
157+
php tests/performance/benchmark.php
158+
159+
# Full benchmark with cross-language comparison
160+
./tests/performance/run-all.sh --compare
161+
162+
# Memory profiling
163+
php tests/performance/memory-profile.php --detailed
164+
165+
# Stress testing
166+
php tests/performance/stress-test.php
167+
168+
# Generate HTML report
169+
php tests/performance/generate-report.php
170+
```
171+
172+
## Key Takeaways
173+
174+
1. **Throughput**: PHP djot-php processes ~2-3 MB/s of djot content
175+
2. **Scaling**: Performance scales linearly with document size (O(n))
176+
3. **vs JavaScript**: Reference JS implementation is ~2x faster
177+
4. **vs Python**: PHP is ~2x faster than Python markdown libraries
178+
5. **Large documents**: 1 MB in ~0.5s (44 MB RAM), 10 MB in ~6s (408 MB RAM)
179+
6. **Memory**: Scales ~40x input size (1 MB input → 44 MB peak)
180+
7. **Safe mode**: No significant performance penalty

tests/performance/.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Results (generated)
5+
results/
6+
7+
# Lock files
8+
package-lock.json
9+
10+
# Python cache
11+
__pycache__/
12+
*.pyc

0 commit comments

Comments
 (0)