Skip to content

Add allocation cache for ConvexConvexSutherlandHodgman clipping#414

Draft
asinghvi17 wants to merge 1 commit into
mainfrom
as/cache-sutherlandhodgman
Draft

Add allocation cache for ConvexConvexSutherlandHodgman clipping#414
asinghvi17 wants to merge 1 commit into
mainfrom
as/cache-sutherlandhodgman

Conversation

@asinghvi17

Copy link
Copy Markdown
Member

Summary

ConvexConvexSutherlandHodgman is the fast path for convex-convex polygon intersection, the kind of routine that gets called in a hot loop (e.g. coverage/regridding over many cells). Previously every call allocated a fresh vector per clip edge — m+1 vector allocations plus growth reallocations for an m-gon clip polygon. Since the algorithm is purely iterative (one pass per clip edge), all intermediate state can live in reusable buffers.

This PR adds an exported SutherlandHodgmanCache{P} with two ping-pong buffers (shared by both manifolds) plus clip/subject buffers for the spherical path. It is threaded through as a keyword argument:

alg = GO.ConvexConvexSutherlandHodgman()
cache = GO.SutherlandHodgmanCache(alg)
for (a, b) in polygon_pairs
    result = GO.intersection(alg, a, b; cache)
end
  • cache = nothing (the default) allocates fresh buffers per call — identical behavior to before, always thread-safe.
  • The returned polygon is copied into a fresh, exactly-sized ring, so results never alias the cache and remain valid after the cache is reused.
  • A cache with the wrong point type for the manifold/float combination throws a descriptive ArgumentError (constructors SutherlandHodgmanCache(alg, T) / SutherlandHodgmanCache(manifold, T) get this right automatically).
  • Thread safety: deliberately left to the caller — one cache per task. This is documented in the docstring; a task-local convenience could be layered on later.

Octagon-octagon benchmark: 928 bytes/call uncached → 448 bytes/call cached (just the returned polygon).

Test plan

  • Existing ConvexConvexSutherlandHodgman tests pass unchanged
  • New Cache testset: cached vs uncached result equality (planar + spherical), aliasing regression (reusing a cache must not corrupt previously returned polygons), wrong-cache-type ArgumentError, and a post-warm-up allocation bound

🤖 Generated with Claude Code

Add an exported `SutherlandHodgmanCache` that holds reusable ping-pong
buffers for the Sutherland-Hodgman edge-clipping loop, threaded through
`intersection` via the `cache` keyword argument. With a cache, the only
remaining allocation is the returned polygon itself. The default
(`cache = nothing`) allocates fresh buffers per call and is always
thread-safe; sharing an explicit cache across tasks is the caller's
responsibility.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant