# Benchmark

This vignette presents pre-computed benchmark results comparing `unigd` rendering performance against base R graphics devices and popular alternatives.

Benchmarks are generated offline by running `Rscript bench/run.R` from the package root. The vignette itself does not execute any benchmark code.

## Test Plots

scatter_small
100 points
scatter_large
10,000 points
lines
5 time series with legend
polygons
50 semi-transparent rects
text_heavy
200+ text labels
ggplot_complex
Faceted scatter + smooth

## Methodology

Each device renders every test plot using `bench::mark()` with a minimum of 5 iterations. Output file sizes are captured from a separate run.

Raster devices use 720 x 576 px; vector devices use 10 x 8 in (720 x 576 px equivalent at 72 dpi).

The timing tables show the median time and a ratio comparing each alternative device to the corresponding base R device (`base::svg`, `base::png`, etc.), so values below 1.0x mean faster than base R.

A note on Cairo backends: unigd uses Cairo under the hood for PNG, PDF, and TIFF output. Comparisons with `Cairo::CairoPNG`, `Cairo::CairoPDF`, etc. therefore isolate device pipeline overhead (recording, serialization, file I/O) rather than rasterizer differences.

The charts show individual iteration times as jittered points with a median crossbar, giving a sense of run-to-run variability.

## Environment

Results were generated on Windows (x86-64, windows) with R version 4.5.2 (2025-10-31 ucrt) at 2026-02-15 23:34 UTC.

CPU: Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz

Package versions: unigd 0.2.0, bench 1.1.4, svglite 2.2.2, ragg 1.5.0, Cairo 1.7.0, ggplot2 4.0.2

## SVG

unigd’s deferred rendering architecture records graphics commands first, then serializes on demand. This avoids redundant intermediate state and tends to show an advantage on complex plots.

Plot | base::svg | svglite | Cairo::CairoSVG | unigd svg
--- | --- | --- | --- | ---
scatter_small | 6.2 ms | 6.4 ms (1.0x) | 11.4 ms (1.8x) | 5.2 ms (0.8x)
scatter_large | 134 ms | 122 ms (0.9x) | 266 ms (2.0x) | 31.5 ms (0.2x)
lines | 18.0 ms | 27.9 ms (1.6x) | 26.0 ms (1.4x) | 9.8 ms (0.5x)
polygons | 7.5 ms | 8.3 ms (1.1x) | 10.2 ms (1.4x) | 6.8 ms (0.9x)
text_heavy | 42.0 ms | 38.1 ms (0.9x) | 182 ms (4.3x) | 33.6 ms (0.8x)
ggplot_complex | 552 ms | 607 ms (1.1x) | 566 ms (1.0x) | 563 ms (1.0x)

SVG

## PNG

Plot | base::png | ragg::agg_png | Cairo::CairoPNG | unigd png
--- | --- | --- | --- | ---
scatter_small | 22.0 ms | 25.5 ms (1.2x) | 29.7 ms (1.3x) | 27.9 ms (1.3x)
scatter_large | 108 ms | 43.4 ms (0.4x) | 51.0 ms (0.5x) | 43.4 ms (0.4x)
lines | 76.4 ms | 37.6 ms (0.5x) | 53.2 ms (0.7x) | 46.3 ms (0.6x)
polygons | 25.4 ms | 26.1 ms (1.0x) | 26.7 ms (1.0x) | 27.5 ms (1.1x)
text_heavy | 167 ms | 84.5 ms (0.5x) | 49.3 ms (0.3x) | 59.5 ms (0.4x)
ggplot_complex | 648 ms | 617 ms (1.0x) | 628 ms (1.0x) | 611 ms (0.9x)

PNG

## PDF

Plot | base::pdf | Cairo::CairoPDF | unigd pdf
--- | --- | --- | ---
scatter_small | 6.0 ms | 14.5 ms (2.4x) | 9.2 ms (1.5x)
scatter_large | 36.1 ms | 78.7 ms (2.2x) | 75.4 ms (2.1x)
lines | 19.1 ms | 37.8 ms (2.0x) | 30.0 ms (1.6x)
polygons | 6.2 ms | 11.3 ms (1.8x) | 8.4 ms (1.4x)
text_heavy | 3.9 ms | 35.8 ms (9.1x) | 36.9 ms (9.4x)
ggplot_complex | 548 ms | 584 ms (1.1x) | 601 ms (1.1x)

PDF

## TIFF

Plot | base::tiff | ragg::agg_tiff | unigd tiff
--- | --- | --- | ---
scatter_small | 13.1 ms | 6.5 ms (0.5x) | 19.5 ms (1.5x)
scatter_large | 95.2 ms | 20.3 ms (0.2x) | 33.9 ms (0.4x)
lines | 62.8 ms | 14.1 ms (0.2x) | 37.5 ms (0.6x)
polygons | 12.6 ms | 9.6 ms (0.8x) | 19.6 ms (1.6x)
text_heavy | 143 ms | 61.6 ms (0.4x) | 51.7 ms (0.4x)
ggplot_complex | 647 ms | 595 ms (0.9x) | 575 ms (0.9x)

TIFF

## File Sizes

Format | base | svglite | ragg | Cairo | unigd
--- | --- | --- | --- | --- | ---
SVG | 53.3 KB | 11.9 KB | — | 53.1 KB | 11.5 KB
PNG | 4.1 KB | — | 22.8 KB | 25.6 KB | 23.0 KB
PDF | 10.3 KB | — | — | 23.3 KB | 23.3 KB
TIFF | 1.2 MB | — | 1.2 MB | — | 20.1 KB

Filesize

Notable: unigd TIFF output uses compression, producing files ~20x smaller than `base::tiff` and `ragg::agg_tiff` which default to uncompressed TIFF.

## Summary

These results are specific to one machine and configuration.

- unigd SVG benefits from deferred rendering – graphics commands are recorded first, then serialized when output is requested. This avoids redundant work on complex plots.
- PNG: all Cairo-based devices (`base::png`, `Cairo::CairoPNG`, unigd) perform similarly since they share the same rasterizer. `ragg::agg_png` uses its own AGG backend and can be faster on some workloads.
- PDF: `base::pdf` uses R’s built-in PDF writer and is consistently the fastest. unigd and `Cairo::CairoPDF` both use Cairo and show similar overhead.
- TIFF: `ragg::agg_tiff` is the fastest raster device here. unigd TIFF is slower on most plots but produces dramatically smaller files thanks to compression.

To reproduce on your own system:

    Rscript bench/run.R