Hazel performance analysis · ^report(12) · 2026-10-13

Moving a group, not its points

If the Drawing library's picture were a tree of groups, each with a transform, instead of a flat list of polygons, how much smaller would a slider's picture diff be, and would the computation follow? ^report(11) estimated the first from the shapes alone, and its What next, step 1 asked for the real thing. This report builds it for one slide, Full Body (Figure 1), and measures both.

body and legsneckplaced above the shirt; its length the neckslidershirt and stitchingstretched by the shirt width; its height, itsown pointspantsplaced below the shirt, stretched by its widthsneakers × 2placed below the pants, scaled by the shoesize, one mirroredarmsarm, sleeve, join × 2 eachturned by the arm angle about the shoulderthe shoulder placed by the shirt width; armlength and width, the part's own pointsheadhead, mouthplaced on the neck; the smile and mouth open,their pointsface × 0.45, eyes × 2each eye placed and sized by the eye gap andsize, turned by the eye angle and shapehair (long, long top)placed with the head, scaled by the eye sizehandshand × 2at the arm's end, turned with the arm and bythe hand angleoutline at the hand's size; fill grown to itby a scale; fingers its own
Figure 1. Full Body as a tree of groups, every part drawn from the tree and outlined in the colour of its branch: the body and legs, the arms, the head and the hands. A part is a shape, made in its own coordinates; a group is a transform, placing, turning or scaling everything in it. Beside each part, what places it and what shapes it: a slider either changes a group's transform, and so moves or turns a whole part, or a shape's own points.

Short answers. One slide, Full Body, rebuilt as a picture of groups; the same 27 slider edits as ^report(11); the same three measures (^report(11)'s terms): the picture diff (what the edit changed in the picture), the trace distance (the fewest evaluation steps any update could take again) and the update cost (the steps an actual update takes again). Steps, not time, and in steps, not shares: today's picture, the tree and the tree flattened each take a different number of steps from scratch.

  1. The tree draws today's picture exactly. Flattened, its points are today's to within 6×10−14, in all 28 pictures (before each edit and after).
  2. The picture diff falls to at most 14 nodes on the edits that change the picture (it was up to 39 shapes), and is never larger than before: arm angle 30 shapes to 8 nodes, hand angle 24 shapes to 2 nodes, shirt width 39 shapes to 13 nodes (Figure 2).
  3. What a transform cannot carry, it does not: a hand's outline is a band of fixed width, so it is made at the hand's size, not grown with it (hand size 24 shapes to 14 nodes); bigger eyes widen the head and lift the hair, by design (eye size 7 shapes to 5 nodes).
  4. The tree alone is cheaper to build than today's picture; flattening it is not: drawn from scratch, the tree takes 110,260 evaluation steps, 10% fewer than today's picture's 121,973, since placing a part is one transform instead of moving every point; flattening it takes 37,957 steps more, 148,217 in all (Figure 5).
  5. Not flattened, the computation follows the picture diff: moving or turning a part costs about what an edit that changes nothing costs (4,249 steps). Trace distance, in steps, today's picture to the tree: arm angle 20,206 to 5,104, hand angle 25,026 to 4,807, neck 10,887 to 5,154; widening the shirt 25,506 to 9,196; growing a hand 28,484 to 14,108. The eye edits gain least (eye size 61,876 to 50,937): most of their steps are the check that keeps the mouth clear of the eyes, which the tree does not change (Figure 6).
  6. Flattened at the end, the gain is gone: flattening walks the whole tree and puts the flat list together again after every edit, 3,247 to 28,018 steps more than the tree alone, so most edits cost more than today (arm angle 20,206 to 28,849); the eye edits come out about even.
  7. Some of the tree's work is redone whatever the edit: an edit that changes nothing in the picture costs 4,249 steps in the tree, 1,085 today. Which work that is, is not broken down here (What next).
  8. Hazel's update today does not change: it evaluates the figure again whole, 85.2 to 89.0% of a run from scratch on today's picture and 81.5 to 87.7% on the tree (104,193 and 90,238 steps for an arm-angle edit). The figure is one top-level binding, so the smaller diffs help only an update that can keep parts of a run (^report(11)).

The picture diff

Picture diff for each slider edit that changes the pictureshirt width3913arms (up / down)308arm length308hand size2414hand angle242shirt height95neck94smile85eye size75arm width66shoe size42eye gap42eye shape (round / narrow)22eye angle22shine size22today: shapes changed, of 49groups: nodes changed, of 82
Figure 2. Each of the 15 slider edits on Full Body that changes the picture without changing how many shapes it has: the shapes it changes in today's picture, a flat list of 49 polygons, against the nodes it changes in the tree of groups, 82 nodes (49 shapes and 33 groups). A group counts as changed when its transform does, a shape when its points or style do; a group's children are matched by their longest common subsequence, and a node on one side only counts with everything in it. Differences below 10−9 count as none, in both: turning a shine and turning it back moves it 9×10−16.

Today the Drawing library places a part of the figure by moving every one of its points, so a slider that moves a part changes every shape in it: the arm-angle slider moves both arms and both hands, 30 shapes. In the tree, a part is a group: its shapes stay in its own coordinates, and its transform puts it in its parent's. The arm-angle slider changes the transforms of the two arms, their sleeves, the sleeves' joins to the shirt and the two hands, and no shape at all: 8 nodes. The same goes for the other placements: the neck on the body, the face on the neck, the hair on the face, the shoes on the feet. Figure 3 draws the whole tree.

body and legsshifted · placedabove the shirt, at (160, 60)neckits points: the neck lengthplacedbelow the shirt: its width and heightmirrored (the right shoe)left to right, one shoe onlyscaledthe shoe sizesneakers (3 shapes)made once, at size 100placed · stretchedbelow the shirt; stretched by its widthpantsmade oncestretchedthe shirt widthshirt, stitchingtheir points: the shirt heightarms (× 2 each)armturned by the arm angle about theshoulderarmits points: arm length and widthsleevethe same turn, the same shouldersleeveits points: arm length and widthjointhe same turn, over the shirtsleevewhere the sleeve meets the shirtheadshifted · placedon the neck: its length, the smileheadits points: eye size, smileface× 0.45, at (115, 70)eye (× 2)placed and sized: eye gap, eye sizeturnedthe eye angle and shapepupila circleshinenot turned: the shine sizemouthits points: smile, mouth openplaced · scaledwith the head; scaled by the eye sizehair: long, long topmade oncehands (× 2)handat the arm's end: arm angle, arm length,shirt widthturnedthe hand angleoutline (6 shapes)a band at the hand's size; thefingersgrownthe hand size, as a scalefill (6 shapes)made once, at size 14; thefingers
Figure 3. The whole tree, in four branches, as Full Body builds it. A group (shaded) is a transform: what it places, turns or scales its children by, and the sliders that change it; a part (white) is a shape: what its own points depend on. A pair of arms, sleeves, joins, eyes, hands or shoes is one subtree drawn twice; a group with two names is a chain of two (placed, then scaled). The hand and the eye are drawn in full in Figure 4.
handat the arm's end, turned with the armturnedthe hand angleoutline (6 shapes)a band 2.5 wide, at the hand's sizegrownthe hand size, as a scalefill (6 shapes)made once, at size 14eyeits place and its size, one transformturnedthe eye angle and shapepupil (1 shape)a circle of radius 10shine (1 shape)not turned: toward the light
Figure 4. A hand and an eye as groups. The hand is placed at the end of its arm and turned with it; inside, it is turned by the hand angle, and its fill is made once, at size 14, and grown to its size by a group's scale. The eye is placed and sized by one transform; inside, it is turned and narrowed by another, and its pupil is a circle of radius 10. A leaf (white) is a shape; a group (shaded) a transform.

What a transform cannot carry

A transform moves, turns and scales a group as a whole. Three things in Full Body are not a whole moved, turned or scaled, and the tree keeps them as shapes made at their own size:

The arm-width slider changes the arms' and sleeves' outlines, a reshaping, not a move: 6 shapes either way.

Building the groups

Steps to draw the figure from scratchtoday's picture121,973groups, flattened148,217groups, not flattened110,260
Figure 5. The evaluation steps to draw Full Body from scratch: today's picture; the tree flattened at the end, as the slide shows it; and the tree alone, not flattened. Steps, counted as the evaluator takes them; deterministic, one run each.

Today the library places a part by moving every one of its points. The tree places a part with one transform, so the tree alone takes 10% fewer steps than today's picture. Flattening it composes every group's transform with its parents' and applies it to every point, and builds the flat list again, list by list: 37,957 steps, more than the tree saved.

The trace distance and the update cost

Trace distance, in evaluation steps (estimated by content)shirt width25,50637,2149,196arms (up / down)20,20628,8495,104arm length20,19029,2296,498hand size28,48435,08514,108hand angle25,02625,8904,807shirt height6,55314,6788,901neck10,88715,8375,154smile18,81723,98313,652eye size61,87659,98450,937arm width2,9279,8596,236shoe size4,0568,7234,838eye gap54,23950,41144,664eye shape (round / narrow)51,03150,02745,830eye angle50,89953,54347,992shine size7,2979,8616,614an edit that changes nothing1,0856,0124,249today's picturegroups, flattened at the endgroups, not flattened
Figure 6. The trace distance of each edit of Figure 2, and of an edit that changes nothing in the picture, in evaluation steps, estimated from above by keying calls on their content (as in ^report(11)): on today's picture, on the tree flattened at the end, and on the tree not flattened. For scale: today's picture takes 121,973 steps from scratch.

A smaller picture diff is a smaller diff of the result. The trace distance is a diff of the computation; on the tree not flattened, it follows the picture diff:

Flattened at the end, every edit pays for the flattening again (3,247 to 28,018 steps more than the tree alone), and the tree's gains are gone: arm angle 20,206 to 28,849, shirt width 25,506 to 37,214, an edit that changes nothing 6,012. Not flattened, the tree is what a renderer that draws groups (SVG's <g transform>, a scene graph) would take.

Hazel's update today: 85.2 to 89.0% of a run from scratch on today's picture, 81.5 to 87.7% on the tree, for the edits of Figure 2; for an arm-angle edit, 104,193 steps on today's picture, 128,194 on the tree flattened, 90,238 on the tree alone. The whole figure is one top-level binding, and Hazel's reuse is by binding (^report(10)), so it is evaluated again whole whatever its representation; it takes fewer steps on the tree alone only because the tree is cheaper to build. The smaller diffs help an update that can keep parts of a run, a memo keyed by names, as ^report(11) measured; they do not help today's.

Every edit

sliderpicture diff, today (shapes)picture diff, groups (nodes)trace distance, today (steps)trace distance, groups flattenedtrace distance, groups not flattenedHazel's update, today (steps)Hazel's update, groups not flattened
shirt width391325,50637,2149,196108,55896,741
arms (up / down)30820,20628,8495,104104,19390,238
arm length30820,19029,2296,498104,18990,234
hand size241428,48435,08514,108104,18990,234
hand angle24225,02625,8904,807110,02590,263
shirt height956,55314,6788,901108,04896,147
neck9410,88715,8375,154105,19791,277
smile8518,81723,98313,652104,18990,234
eye size7561,87659,98450,937104,02590,070
arm width662,9279,8596,236104,18990,234
shoe size424,0568,7234,838104,18990,234
eye gap4254,23950,41144,664102,42988,474
eye shape (round / narrow)2251,03150,02745,830104,18990,234
eye angle2250,89953,54347,992104,02990,074
shine size227,2979,8616,614104,18990,234
human fingerschanges the count104100,391152,59680,353184,214153,124
iris sizechanges the count970,27567,26955,568112,42494,701
mouth openchanges the count641,53043,49833,068134,282111,148
alien fingers001,0856,0124,249104,18990,234
star points001,0856,0124,249104,18990,234
star turn (% to the next point)001,0856,0124,249104,18990,234
claws001,0856,0124,249104,18990,234
claw length001,0856,0124,249104,18990,234
eye whites001,5745,9954,232104,18990,234
spiky teeth001,0705,9954,232104,18990,234
tongue length001,9446,8695,106104,18990,234
tongue width001,9876,9125,149104,18990,234

Steps, counted as the evaluator takes them. From scratch: today's picture 121,973, the tree flattened 148,217, the tree alone 110,260. Edits that change how many shapes there are (the number of fingers, an iris, opening the mouth) change which calls are made; their picture diff in the flat picture is not a shape-by-shape count. Edits whose picture diff is 0 move a slider of a style Full Body is not wearing (claws, stars, alien fingers, spiky teeth, a tongue), or eye whites, which show only with an iris.

What next

  1. Draw the groups. Let the Drawing library's ^picture take a tree and render it as SVG groups, so the picture diff of Figure 2 reaches the page, and time a slider release against today's.
  2. Find the floor. Break down the 4,249 steps an edit that changes nothing costs in the tree (against 1,085 today), with ^report(11)'s diagnosis of which calls' inputs differ.
  3. Flatten only what changed. A flattening that keeps each group's flat shapes, keyed by the group and its composed transform, would not put the whole list together again after an edit; measure its trace distance against the tree's.
  4. The other slides. Rebuild Witch and Scenes as groups, where ^report(11) found the largest flat diffs (the witch's woods, the red eyes, a shared symbol for repeated shapes).
  5. An outline that a group can scale. Try a fixed-width stroke for hand outlines and measure the hand-size slider again, with the picture checked by eye.

How this was put together