Tetrahedral_remeshing: replace hash containers with linear scans over small, bounded sets - #9594
Open
IasonManolas wants to merge 4 commits into
Open
Conversation
…ell set is_cells_set_manifold() counted, for each facet of a candidate cell set, how many times each vertex triple appears, via a hashed vertex-triple-to-count map, to find facets shared by exactly one cell (the boundary of the set). The triangulation already knows which facets border a given cell set: a direct cell-neighbor lookup replaces the hashed triple counting.
…tainers CollapseTriangulation's constructor numbered the star's ~20 vertices via an unordered_set plus an unordered_map, hashing a compact-container iterator through Time_stamper for each. A small_vector of pairs with linear scan replaces both, since a star this small is cheaper to scan than to hash.
…order The collapse work list is a bimap whose element side was set_of<Edge, Compare_edges>, an ordered container, so every membership test (the priority update or erase that follows each collapse) cost O(log n) comparisons, each building and comparing canonical vertex pairs. That side is never iterated in order; only the priority side is, and it is untouched. Switched to unordered_set_of with matching Hash_edges and Equal_edges.
…ash set nb_incident_subdomains() and nb_incident_surface_patches() filled an unordered_set with every index seen around a vertex or edge just to read its size back out, for a count that is almost always 1 or 2. Replaced with an inline small_vector and linear dedup.
janetournois
approved these changes
Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four independent optimizations, grouped together because each replaces a hash-based container
with a direct lookup or a linear scan, in places where the container never holds more than a
handful of elements, so hashing costs more than it saves:
is_cells_set_manifold()counted,for each facet of a candidate cell set, how many times each vertex triple appears, via a hashed
vertex-triple-to-count map, to find facets shared by exactly one cell (the boundary of the
set). The triangulation already knows which facets border a given cell set: a direct
cell-neighbor lookup replaces the hashed triple counting.
CollapseTriangulation'sconstructor numbered the star's roughly twenty vertices via an
unordered_setplus anunordered_map, hashing a compact-container iterator for each. Asmall_vectorof pairs withlinear scan replaces both, since a star this small is cheaper to scan than to hash.
bimapwhose element side was
set_of<Edge, Compare_edges>, an ordered container, so every membershiptest (the priority update or erase that follows each collapse) cost O(log n) comparisons, each
building and comparing canonical vertex pairs. That side is never iterated in order; only the
priority side is, and it is untouched. Switched to
unordered_set_ofwith matchingHash_edges/Equal_edges.nb_incident_subdomains()andnb_incident_surface_patches()filled anunordered_setwith every index seen around a vertexor edge just to read its size back out, for a count that is almost always 1 or 2. Replaced with
an inline
small_vectorand linear dedup.Testing
Verdict equivalence. All four changes are alternative implementations of the same predicate
or count; none change which candidate is evaluated, selected, or in what order. Full test suite
(all executables in
test/Tetrahedral_remeshing) passes.Byte-identical output, against plain
cgal/main:Performance.
perf stat -e instructions, Linux, Release, sequential, measured withPR #9587 applied as the base, since that PR's decisive-accept fast path already skips
CollapseTriangulationfor most candidates and changes how often the second optimization abovegets exercised. Byte-identical to that base on all three meshes.
Release Management