Skip to content

Use SVG as a branch-to-data renderer benchmark #39

Description

@isomorphisms

Sequencing status — 2026-08-27

Later integration benchmark only. Follow #41 and isomorphisms/idric-arm-thumb#31. Do not start an SVG implementation before tokenization, bounded tree traversal, typed scene/display-list records, and scalar raster primitives are independently settled. SVG must not become the place where several missing Idriç layers are designed implicitly.

Goal

Treat a deliberately small SVG renderer as a browser workload that spans the whole transition from branch-heavy interpretation to regular numeric/pixel work.

The useful shape is:

SVG/XML bytes
  → tokenization / parsing
  → element + style dispatch
  → path/shape commands
  → transforms / clipping / filling
  → geometric primitives / coverage
  → rasterization
  → pixel blending
  → framebuffer

The front half contains many finite decisions; the back half should increasingly become regular numeric work. The experiment is to make that transition explicit instead of repeatedly interpreting SVG tags, path opcodes, and style properties all the way down to paint.

First narrow fixture

Do not aim at standards-complete SVG. Start with an exact deterministic subset:

  • <svg> viewport;
  • <rect> and <circle>;
  • one simple <path> using a small command set such as M, L, Z;
  • solid fill;
  • one affine transform;
  • clipping only after the basic fixture is green;
  • text, gradients, filters, masks, animation, and external resources later.

Keep both a semantic scene/display-list oracle and an exact or tolerance-defined pixel oracle so control-flow changes cannot silently change rendering.

Branch-heavy stages to isolate

Measure separately rather than calling the whole renderer "branchy":

  • XML/token dispatch;
  • SVG element dispatch (rect, circle, path, ...);
  • attribute/style/property dispatch;
  • path-command dispatch (M, L, C, Q, A, Z, ... as support grows);
  • clipping/fill edge decisions;
  • paint/display-list opcode dispatch.

Then identify where those decisions can be compiled/classified once into compact data:

  • dense element/path/paint tags;
  • decision or transition tables;
  • compact display lists;
  • precomputed transforms/style records;
  • geometry batches;
  • masks/coverage buffers.

The rasterization/blending tail should be evaluated as a separate increasingly regular numeric/parallel workload, not forced through the same control-flow strategy as parsing.

Comparison ladder

  1. straightforward scalar/reference implementation;
  2. classify/normalize once into compact typed records;
  3. table/jump-table/decision-table dispatch where profitable;
  4. batched geometry/raster loops;
  5. SIMD/GPU only as later comparisons, not prerequisites.

Measurements

Keep at least:

  • exact normalized scene/display-list output;
  • rendered bitmap oracle;
  • static and dynamic branch counts where available;
  • time spent in parse/dispatch/geometry/raster/blend separately;
  • code/data size for dispatch tables;
  • time to first useful paint;
  • regressions/non-wins.

Companion issues

Related

The companion compiler/backend issues preserve and lower the same branch-to-data boundary rather than baking browser semantics into one backend.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions