BLT-faster

A patch for BLT 2.4 that caches axis tick labels and static chrome to cut graph-redraw cost. Measured ~1.3–1.9x, pixel-identical output.

BLT-faster on GitHub →

What it is

BLT-faster is a C patch against the BLT 2.4 graph / stripchart / barchart widget that reduces the per-frame cost of live, continuously-redrawn charts, with no change to rendered output. It targets the BLT 2.4 tree as bundled in AndroWish / undroidwish and most other BLT 2.4 distributions.

It ships as a GPL-3 patch project: it distributes patches/blt-faster.patch plus documentation, not the BLT source. Apply the patch to a pristine BLT 2.4 tree and rebuild; the changes apply to every graph.

The performance problem

Profiling case: three live espresso charts (pressure, flow, temperature) redrawing at 10 Hz on a tablet. Findings:

The approach is to avoid repeating the axis work every frame.

The optimizations

-cachelabels — the label cache (default ON)

Each unique axis tick-label string is rendered once into a small pixmap (on the axis-margin background, where there is no grid underneath) and then blitted at its new position each frame instead of re-rasterizing the text.

-bufferchrome — chrome buffering (default OFF, opt-in)

The entire static "chrome" (background, grid, tick labels, axes, border) is rendered once into a cache pixmap and reused, drawing only the data elements on top.

-redrawduty / -minredrawms — redraw throttling (designed)

A separately-designed redraw-pacing pair of options that limits how often expensive redraws run on slow hardware:

This is a responsiveness / CPU-budget change (it can free ~40 % CPU on a slow tablet where stock BLT leaves only ~8 % headroom), not a chart-freshness fix — keeping the chart up to date instead relies on cheaper redraws (-bufferchrome plus a stepped rather than grow-every-frame x-axis). It composes with the label cache and chrome buffering. These options are designed and documented but not part of the applied patch yet.

Results

Measured on an Apple M4, using a reproduction of the 3-chart live espresso page (pressure / flow / temperature), full element set, 10 Hz over a 45 s "shot":

chart kind stock BLT BLT-faster speedup
live charts, auto-scaling x-axis (1280×800) 5.3 ms/frame 3.9 ms/frame 1.34× (-cachelabels)
fixed-axis graph (history / zoomed / dashboard) 3.8 ms/frame 2.0 ms/frame 1.9× (-bufferchrome)
slow tablet, -redrawduty frees ~40 % CPU

The relative speedup typically grows on slower hardware (tablets, single-board computers), where text rasterization is comparatively more expensive than on a fast desktop.

Measurement note: benchmark the on-screen redraw path (update idletasks), not $graph snap. Snap forces a full reset-world redraw plus a photo read-back and bypasses -bufferchrome, so it does not reflect real live-redraw cost.

How to apply

From the root of a BLT 2.4 source tree (the directory containing src/):

patch -p1 < /path/to/BLT-faster/patches/blt-faster.patch
# ...then rebuild BLT the way you normally do.

Or use the helper:

./apply-patch.sh /path/to/blt

The patch touches four files (src/bltGraph.{c,h}, src/bltGrAxis.{c,h}), adds roughly 375 lines, and is additive: with the options at their defaults the rendering is identical to stock BLT. After rebuilding, every graph has -cachelabels on; enable -bufferchrome per graph:

.g configure -bufferchrome 1     ;# opt IN to the chrome cache (default off)
.g configure -cachelabels  0     ;# opt OUT of the label cache (default on)

BLT loads as a runtime library, so a test script can load the patched build to override an embedded one without relinking the host wish.

Repository

Source, patch, and documentation (docs/HOW-IT-WORKS.md, docs/BENCHMARKS.md) are on GitHub: github.com/johnbuckman/BLT-faster. GPL-3.0. The patch and docs are original work; they modify BLT, which carries its own license — this repo distributes the changes, not the BLT source.