| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Sorry, something went wrong.
📲 Install BuildsAndroid
|
Sorry, something went wrong.
Performance metrics 🚀
Baseline results on branch: mainStartup times
App size
Previous results on branch: no/java-534-findtarget-point-transformStartup times
App size
|
Sorry, something went wrong.
There was a problem hiding this comment.
Great work! (And love the helper doc.)
One optional comment; otherwise lgtm
Sorry, something went wrong.
There was a problem hiding this comment.
dope! I wish my Algebraic geometry teacher had told me what would I need matrices for 😅
Sorry, something went wrong.
ViewUtils.findTarget called View.getLocationOnScreen for every visited view, and that walks from the view up to the root each time, making the traversal O(N*depth) per tap and scroll start. Instead, map the touch point down into each child's local coordinate space as we descend the tree — the same way ViewGroup dispatches touch events — so each view costs O(1) and the whole traversal is O(N). The locators still receive the original decor-view-relative coordinates, since the Compose locator hit-tests against window coordinates. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…g (JAVA-534) The existing test only exercised the left/top offset path of mapToChild. Add cases for a scrolled parent and a non-identity child matrix so the other two coordinate-mapping branches are covered, and switch the class to Robolectric so the real Matrix math runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
📜 Description
ViewUtils.findTarget (run on every tap and at every scroll start) called View.getLocationOnScreen for every visited view to hit-test it. getLocationOnScreen walks from the view up to the root each call, so hit-testing the whole tree was O(N·depth) per gesture, repeatedly re-walking the same ancestor chains.
This replaces that with the technique ViewGroup itself uses to dispatch touch events: map the touch point down into each child's local coordinate space as we descend (offset by the parent's scroll and the child's left/top, then apply the child's inverse matrix for transformed views). Each view is then a cheap O(1) bounds check against its own [0,0,width,height], making the whole traversal O(N).
Notes:
The sentry-compose locator gets the same LinkedList→ArrayDeque cleanup (it already hit-tests in window space, so no coordinate change there).
💡 Motivation and Context
JAVA-534 / #5481. Follow-up to #5594 — that PR removed the queue-node allocations; this one removes the per-view getLocationOnScreen call, replacing an O(N·depth) traversal with O(N).
Tradeoff: carrying the per-view local coordinates through the BFS needs a small holder object per node, so this re-introduces a per-node allocation that #5594 removed. That is an intentional trade — avoiding the repeated O(depth) ancestor walk per view in exchange for a short-lived gen-0 object.
A micro-benchmark (see testing notes) measures a ~4–5× speedup of the traversal on large view trees, scaling down to ~1.7× on trivial ones — the win is proportional to how many views sit under the touch.
💚 How did you test it?
Timing — micro-benchmark. Profiler-based measurement didn't work: on the test device (Pixel 3, Android 12) instrumented method tracing produces empty traces, fine-grained sampling overflows the buffer, and at the only working sampling rate (1 ms) findTarget (~0.3 ms) is below the resolution — run-to-run variance dwarfs the difference. So I wrote a JVM micro-benchmark instead (not committed — it was a one-off).
What it does: builds one real, attached, laid-out View tree and times both hit-testing strategies over it — old (getLocationOnScreen per view) vs new (point-transform-during-descent) — 800 iterations × 6 rounds each, alternating order with warmup, on a release/R8 build. Only the per-view bounds computation differs between the two paths (the part this PR changes); the locator loop is excluded since it's identical for both. The tree is built so every node contains the touch point, forcing a full N-node traversal, and is swept across four sizes. Median of two runs:
So getLocationOnScreen costs ~1 µs/view, the new transform ~0.2 µs/view → a steady ~4–5× on the traversal, with absolute savings scaling from a few µs on a trivial screen to ~250 µs on a dense 300-view one. This is a per-tap / per-scroll-start main-thread cost (well under one frame even at the high end), not a frame-rate or startup change. Speedup ratios reproduced within ~8% across runs; absolute numbers drift with device thermals.
📝 Checklist
🔮 Next steps
None.