Skip to content

Djot-PHP Performance Summary

Performance benchmarks for djot-php compared to other implementations.

Test Environment:

  • PHP 8.4.21 (OPcache enabled)
  • Node.js v22.22.2
  • Python 3.12.3
  • Rust (jotdown 0.7)
  • Go (godjot v1.0.6)
  • Linux 6.17.0-35-generic

NOTE

The djot-php tables below (size scaling, content type, safe mode, memory) were re-measured June 2026. The cross-implementation tables (PHP alternatives, cross-language, profiles) are pending a re-measurement on an unloaded machine and still show the previous figures.

Quick Reference

Document SizePHP FullThroughput
1 KB0.51 ms~2.1 MB/s
11 KB5.2 ms~2.1 MB/s
56 KB26 ms~2.2 MB/s
225 KB118 ms~1.9 MB/s
1 MB605 ms~1.9 MB/s

PHP Alternatives Comparison

With equivalent features enabled (tables, footnotes, smart typography):

Library30KB DocThroughputvs djot-php
erusev/parsedown1.69 ms16.0 MB/s6.7x faster
michelf/php-markdown5.16 ms5.2 MB/s2.2x faster
michelf/php-markdown (Extra)6.15 ms4.4 MB/s1.9x faster
djot-php11.36 ms2.6 MB/sbaseline
league/commonmark (GFM)15.00 ms1.8 MB/s1.3x slower
league/commonmark15.31 ms1.8 MB/s1.4x slower
league/commonmark (Full)23.54 ms1.3 MB/s2.1x slower

Key finding: djot-php is 2x faster than CommonMark when both have equivalent features (tables, footnotes, smart punct) enabled.

Cross-Language Comparison

Benchmarked on medium-sized documents (~56 KB):

ImplementationMean TimeThroughputvs PHP
Rust (jotdown)~1-2 ms~30+ MB/s~12x faster
Go (godjot)~2-4 ms~15+ MB/s~6x faster
JS (@djot/djot)8.1 ms5.2 MB/s2.8x faster
PHP (djot-php)23 ms2.4 MB/sbaseline
Python-Markdown*41.1 ms1.0 MB/s1.8x slower

*Python libraries are Markdown parsers (no Djot implementation exists for Python).

Document Size Scaling

PHP djot-php scales linearly with document size:

SizeInputMedian TimeThroughput
tiny1.1 KB0.51 ms2.1 MB/s
small11.1 KB5.24 ms2.1 MB/s
medium56.1 KB25.92 ms2.2 MB/s
large225.5 KB118.09 ms1.9 MB/s
huge1.1 MB605.36 ms1.9 MB/s

Content Type Performance

Different content types have varying performance characteristics:

Content TypeSizeMedian TimeThroughputNotes
code_heavy5.8 KB1.74 ms3.4 MB/sFastest - simple parsing
nested_lists5.6 KB3.14 ms1.8 MB/sAverage
tables9.2 KB5.13 ms1.4 MB/sTable parsing overhead
complex8.9 KB5.28 ms1.7 MB/sMany features
inline_heavy14.8 KB9.16 ms1.3 MB/sMany inline elements

Code-heavy documents are fastest because code blocks require minimal parsing.

Profile Performance

Different profiles have similar performance since they filter the same AST:

ProfileMean TimeNotes
none20.70 msNo filtering
full22.10 msAll features enabled
article21.80 msBlog/article content
comment23.27 msUser comments
minimal22.90 msBasic text formatting

Safe Mode

Safe mode has negligible performance impact:

ModeMedian Time
Disabled24.88 ms
Enabled25.04 ms

Config Lever Cost: blocksInterruptParagraphs

The blocksInterruptParagraphs lever lets a top-level block element interrupt a paragraph without a blank line in front of it (markdown-style). Its cost depends entirely on whether a document actually triggers that path. Relative A/B on equivalent ~50 KB documents:

Document shapevs default
Plain prose (paragraphs separated by blank lines)no measurable change
Block abutting every paragraph (no blank line)~50% slower

Enabling the lever is effectively free for normal documents: when no block ever abuts a paragraph, the extra check costs nothing measurable. The overhead only appears on the markdown-style content the lever exists for, where each interruption splits one paragraph into a paragraph plus a separate block and therefore parses and builds more nodes. The slowdown is proportional to how often blocks abut paragraphs, not a fixed tax.

Memory Usage

Memory scales approximately linearly with document size:

Input SizePeak MemoryRatio
11 KB66 MB~6100x
57 KB66 MB~1200x
226 KB68 MB~310x
1 MB~80 MB~80x

Note: PHP has a base memory overhead. The incremental memory per input byte is approximately 30-45x.

Running Benchmarks

bash
# Internal PHP benchmark
php tests/benchmark/benchmark.php

# PHP alternatives comparison
cd tests/benchmark_alternatives
composer install
php benchmark.php

# Cross-language comparison
./tests/benchmark/run-all.sh --compare

Key Takeaways

  1. Throughput: PHP djot-php processes ~1.9-2.2 MB/s of djot content (with OPcache)
  2. vs CommonMark (Full): djot-php is 2x faster with equivalent features
  3. vs Parsedown: Parsedown is 6-7x faster but lacks advanced features
  4. Scaling: Performance scales linearly with document size (O(n))
  5. vs Rust/Go: Native implementations are 6-12x faster (as expected)
  6. vs JavaScript: Reference JS implementation is ~3x faster
  7. Safe mode: No significant performance penalty
  8. OPcache: Enable OPcache for best performance (~2x improvement)

Released under the MIT License.