zgx

Microbenchmarks

One state change, and one scroll step of 10,000 rows, timed headless in process CPU per operation, from the change to a frame ready to present.

Each figure is the median over batches after a warm-up, with the 10th to 90th percentile beside it. Each framework’s frame is compared with the frames that do the same work: GPUI Fast’s headless frame stops before the GPU encode, so it sits beside zgx’s frame without one; Rune’s and MyGo’s include it (MyGo’s also rasterizes on the CPU), beside zgx’s with it. Lower is better.

State updateµs of CPU per operation. One counter bound to one text, over a static grid of 1,000 texts: set the counter.
FrameFrameworkMedian (p10–p90)
Without the GPU encodezgx
1.9(p10 1.7 to p90 2.2)
zgx (Luau)
2.4(p10 2.2 to p90 2.5)
GPUI Fast
675(p10 660 to p90 685)
With the GPU encodezgx
81.6(p10 75.6 to p90 123.0)
zgx (Luau)
60.7(p10 56.2 to p90 81.3)
Rune
1,424(p10 1,384 to p90 1,454)
MyGo
482(p10 461 to p90 495)
Scroll step, fixed rowsµs of CPU per operation. 10,000 rows of 28 pt: scroll 12 pt.
FrameFrameworkMedian (p10–p90)
Without the GPU encodezgx
3.5(p10 3.1 to p90 4.1)
zgx (Luau)
4.2(p10 3.8 to p90 4.9)
GPUI Fast
26.5(p10 24.5 to p90 30.1)
With the GPU encodezgx
91.2(p10 79.3 to p90 100.7)
zgx (Luau)
113(p10 100 to p90 191)
Rune
210(p10 126 to p90 231)
MyGo
209(p10 200 to p90 304)
Scroll step, variable rowsµs of CPU per operation. 10,000 of the list scene's rows (wrapped text, some images), measured as they mount: scroll 12 pt.
FrameFrameworkMedian (p10–p90)
Without the GPU encodezgx
6.9(p10 0.8 to p90 11.5)
zgx (Luau)
9.7(p10 0.8 to p90 14.9)
GPUI Fast
119(p10 99 to p90 137)
With the GPU encodezgx
112(p10 87 to p90 137)
zgx (Luau)
109(p10 86 to p90 143)
Rune
209(p10 174 to p90 278)
MyGo
431(p10 356 to p90 509)
  • The change alone (“write”) is not compared: GPUI Fast, Rune and MyGo store the value and mark the window to draw, leaving all their work to the frame, where zgx’s bindings update their nodes as the value is set. The frame is the figure that counts, and it includes the write.
  • MyGo’s frame rasterizes its scene on the CPU, as its headless tester does, where a window would draw on the GPU; it is shown at a raster scale of 0.05×, which leaves its layout and paint and makes the raster almost free.
  • Most of a frame with the GPU encode is what any Metal frame costs: a bare Metal frame (a command buffer, one empty render pass, commit) takes 44–94 µs of process CPU back to back on this Mac, most of it in Metal’s own threads.

How they are defined and run: microbenchmarks. Raw rows: micro.jsonl.

Edit on GitHub