Skip to content

RayoMD 2.6.0 Performance Snapshot

mkuch edited this page Jul 18, 2026 · 3 revisions

RayoMD 2.6.0 performance snapshot

Run date: 2026-07-18.

This snapshot keeps two measurements separate:

  • a current RayoMD 2.6 warm-generation comparison of tester.md with and without image syntax on Windows and WSL;
  • a Windows fresh-process comparison of the frozen 2.5 release and 2.6.

They answer different questions and their millisecond values should not be compared directly.

tester.md image matrix

Warm generation

The current 2.6 Release builds used modern normal, URL-image fetching off, and ten order-balanced process pairs per platform.

Platform/storage Imageless median (range) Image-bearing median (range) Paired median overhead PDF bytes: no image / image
Windows 11 workspace 0.44749 ms (0.42791-0.50639) 0.71421 ms (0.67085-0.84428) +0.28041 ms (+63.4%) 121,219 / 379,528
Linux WSL /mnt/e 0.22493 ms (0.18790-0.25450) 5.11995 ms (4.97940-6.20240) +4.88740 ms (+2,332%) 184,440 / 494,837

Each Windows process timed 1,000 builds; each WSL process timed 200. Values are calculated from total_ms / iterations, avoiding the CLI's coarser two-decimal avg_ms display. --bench performs an untimed warm-up and sample build, then times repeated in-memory PDF generation. It excludes process startup, source reading, and timed output writing.

Fresh-process (cold-start) export

The existing Python run_export helper in scripts/fresh_process_ab.py timed 32 order-balanced pairs after six preflights per case:

Platform/storage Imageless p50 / p95 (range) Image-bearing p50 / p95 (range) Paired median overhead
Windows 11 workspace 21.096 / 28.240 ms (16.927-29.142) 98.387 / 128.508 ms (83.183-142.421) +76.253 ms (+370.1%)
Linux WSL /mnt/e 25.450 / 31.839 ms (21.347-83.876) 153.630 / 218.485 ms (136.102-236.001) +125.297 ms (+521.9%)

Timing begins immediately before Python launches RayoMD and ends after the process exits. It includes process startup, source reading, PDF generation, output writing, and shutdown. PDF validation happens after the timer. Each run uses a new process, but filesystem and OS caches may remain warm; "cold" here means process-cold, not a machine-wide cache drop.

All measured outputs were stable and matched the warm-run hashes below. The image-bearing median stayed below 100 ms on Windows and below 160 ms on WSL's Windows-mounted workspace.

Fixtures

The image-bearing input is the repository's 3,896-byte tester.md, SHA-256 3b4c208fae9794f617c12a6c29cebfb1d5da007c10d3640525047c395f676a36. It contains:

  • the local RayoMD mascot as a direct and reference-style standalone image;
  • the same reference in paragraph text, which uses the inline fallback;
  • two remote sources that use fallback because URL fetching is off;
  • one missing local source that uses fallback.

The 3,579-byte imageless derivative, SHA-256 a56e529f4ee3effba406d668b941b4577e8e043799943d7076b7ea2c98970beb, removes the five standalone image lines, replaces the inline reference image with its alt text, and removes the now-unused logo-ref definition. It contains no remaining ![ image syntax. All other document content is unchanged.

Correctness

Every one of the ten rounds per platform and case produced the same PDF hash:

Platform Case PDF SHA-256
Windows Imageless 9ba145a8a2088345ed14e4e41aa03ed4af71f7355e338ad1ef764610ece33261
Windows Image-bearing 67b5d19d092d910b573c954018b5b238248c6ac0dcc7fe0f4dd4067dbe9ae400
Linux WSL /mnt/e Imageless 4bef2496ed8dbdb18d26b842c4aebc9a08a7913bc3db4eb42c9f75fa83a86432
Linux WSL /mnt/e Image-bearing 89e94517fe9cd99dc29ced66e299076874cee39fbb4e0614a9ffc2af49cea5c4

Hashes differ across platforms because their embedded system-font resources differ. Both builds passed their two CTest entries.

Environment and interpretation

  • Host: Windows 11 build 26200, AMD Ryzen 5 5600X, 128 GiB RAM.
  • Windows: MinGW-w64 GCC 15.2.0 Release, rayomd 2.6.0, 2,820,608 bytes, SHA-256 289ec3f1baa1d85681add8b48174a5ec3d378fa5dc17c0aa4b66f98659877cb4.
  • WSL: Ubuntu 24.04.1 LTS, GCC 13.3.0 Release, rayomd 2.6.0, 432,688 bytes, SHA-256 ce7d005f06b9dbc08346de690056c6cde95def55a5728cea837b94cd1f858ae2.
  • Source, image, binaries, and outputs were all on the Windows-backed /mnt/e mount for WSL.

On Windows, the image cases add a paired median 0.28041 ms. On WSL /mnt/e, they add 4.88740 ms, or about 24.3 times the imageless time by paired median. That much larger gap is consistent with repeated path and image-file work on DrvFS. It is a Windows-mounted-storage result and must not be generalized to Linux-native/ext4 performance.

The Windows cold image path also pays the deliberately deferred optional image-library load once per process; the warm table shows the steady-state generation cost after that startup work. On WSL, the 125.297 ms paired cold delta includes process startup plus image access on DrvFS. Neither result includes remote-image network time.

Reproduce the warm matrix

Run each command in ten fresh processes, alternating which case runs first:

build\windows\rayomd.exe --bench tester.md benchmark-output\tester-images 1000 modern normal
build\windows\rayomd.exe --bench benchmark-output\tester-imageless.md benchmark-output\tester-no-images 1000 modern normal

WSL from the same /mnt/e checkout:

build/linux/rayomd --bench tester.md benchmark-output/tester-images 200 modern normal
build/linux/rayomd --bench benchmark-output/tester-imageless.md benchmark-output/tester-no-images 200 modern normal

Generate the imageless input with the fixture transformation above and verify its SHA-256 before measuring. Keep URL-image fetching off for both cases.

Windows fresh-process release comparison

RayoMD 2.6 reduces optional Windows startup work for one-shot CLI exports. In an order-balanced same-session comparison against the frozen 2.5 release, the 2.6 Release build reduced fresh-process time 35.8% by paired geometric mean across three image-free workloads. Candidate PDFs were byte-identical to the matching 2.5 outputs.

This is a release-to-release startup result on one Windows host. It is not a universal Markdown-to-PDF ranking or a claim of visual or feature equivalence with broader renderers.

Results

Case Input RayoMD 2.5 median RayoMD 2.6 median Paired median improvement Faster pairs
Tiny README 205 B 19.6959 ms 11.8651 ms 39.9% 31/32
Medium feature mix 15,102 B 21.0559 ms 13.7823 ms 36.7% 32/32
500-row table 33,353 B 22.9131 ms 15.3760 ms 33.8% 32/32

The aggregate same-session geometric means were 21.1809 ms for 2.5 and 13.5982 ms for 2.6. The paired-session improvement was 35.7999%.

What changed in 2.6

The Windows executable now loads optional GUI, shell, networking, and image DLLs only when those paths are needed. One-shot native CLI exports can reach the exporter without eagerly loading those libraries first. CLI parsing compatibility, URL-image opt-in, and the normal GUI path remain available.

The candidate executable grew from 2,812,416 to 2,820,608 bytes (8 KiB, about 0.3%). The startup improvement therefore carries a small, explicit binary-size tradeoff rather than a new runtime dependency.

Method

  • Host: Windows 11 build 26200, AMD Ryzen 5 5600X, 128 GiB RAM.
  • Build: MinGW-w64 GCC 15.2.0, CMake Release configuration.
  • Timing: wall time from fresh process launch through output validation and process exit; filesystem and OS caches may be warm.
  • Sampling: 32 order-balanced A/B pairs per case after six uncounted preflights per binary and case.
  • Inputs: pinned local files with no Markdown or HTML image syntax; URL-image fetching disabled.
  • Baseline: rayomd 2.5.0, 2,812,416 bytes, SHA-256 32b001eee4ff70ed5b8767b3652b88cc4c40473c84b085d277461e2a56cade01.
  • Candidate: rayomd 2.6.0, 2,820,608 bytes, SHA-256 289ec3f1baa1d85681add8b48174a5ec3d378fa5dc17c0aa4b66f98659877cb4.

Pinned input hashes:

Case SHA-256
Tiny README 7a2b7143c3a0b584d21c6aa8daa3ab59763482b51978bff677c3b5cccb71f919
Medium feature mix 5f31800448816969a0be9c45f153b4d642b0336fbbdbe98ec0d52a40d9083f4f
500-row table 33240f4ae881a717a6accf5b37f2603b13f2da4c5598ee7269faee7896af1619

Acceptance caveat

The run met the harness's 20% paired improvement target, stayed within its per-case regression limit, and produced byte-identical PDFs. Its frozen 2.5 baseline geometric mean was 14.2% slower than the earlier reference session, exceeding the strict 5% drift limit. The automated acceptance result was therefore false.

That drift does not reverse the order-balanced same-session result, but it does mean the absolute millisecond values should be treated as host-local. The README uses the paired improvement and carries this caveat here; it does not turn the run into a new cross-tool claim.

Reproduce the startup comparison

Build 2.6 in Release mode and run the maintained harness with an extracted 2.5 release binary and the pinned corpus:

cmake -S . -B build\windows -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake --build build\windows --config Release

python scripts\fresh_process_ab.py `
  --baseline benchmark-output\baselines\rayomd-2.5.0.exe `
  --candidate build\windows\rayomd.exe `
  --corpus benchmark-output\competitors\corpus `
  --root benchmark-output\fresh-process-2.6 `
  --runs 32 `
  --preflights 6 `
  --expected-baseline-sha256 32b001eee4ff70ed5b8767b3652b88cc4c40473c84b085d277461e2a56cade01

Generated JSON records, corpora, PDFs, and binaries belong under ignored benchmark-output/. See Performance Watcher for the broader warm, cold, batch, serve, memory, reversible-PDF, and competitor workflows, and Benchmarks for the dated archive.

Clone this wiki locally