From 4680ad1eb504e87317594ae605b7113e57cc29b9 Mon Sep 17 00:00:00 2001 From: Elias Carvalho Date: Mon, 18 Nov 2024 17:42:46 -0300 Subject: [PATCH 1/4] Avoid allocations in 'vertex' of 'PolyArea' --- src/geometries/polytopes/polyarea.jl | 12 ++++++++++++ test/multigeoms.jl | 2 +- test/polytopes.jl | 20 +++++++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/geometries/polytopes/polyarea.jl b/src/geometries/polytopes/polyarea.jl index 16c912b90..9c4d515d2 100644 --- a/src/geometries/polytopes/polyarea.jl +++ b/src/geometries/polytopes/polyarea.jl @@ -31,6 +31,18 @@ PolyArea(outer...) = PolyArea(collect(outer)) Base.isapprox(p₁::PolyArea, p₂::PolyArea; atol=atol(lentype(p₁)), kwargs...) = length(p₁.rings) == length(p₂.rings) && all(isapprox(r₁, r₂; atol, kwargs...) for (r₁, r₂) in zip(p₁.rings, p₂.rings)) +function vertex(p::PolyArea, ind) + offset = 0 + for r in p.rings + offset′ = offset + offset += nvertices(r) + if ind ≤ offset + return vertex(r, ind - offset′) + end + end + throw(BoundsError(p, ind)) +end + vertices(p::PolyArea) = mapreduce(vertices, vcat, p.rings) nvertices(p::PolyArea) = mapreduce(nvertices, +, p.rings) diff --git a/test/multigeoms.jl b/test/multigeoms.jl index 668582690..5b1dddd6b 100644 --- a/test/multigeoms.jl +++ b/test/multigeoms.jl @@ -112,5 +112,5 @@ multi3 = Multi([poly3, poly4]) vertextest(multi1) vertextest(multi2) - vertextest(multi3, bytes=3100) + vertextest(multi3) end diff --git a/test/polytopes.jl b/test/polytopes.jl index 2f3f26ea8..2a50b8baa 100644 --- a/test/polytopes.jl +++ b/test/polytopes.jl @@ -652,9 +652,27 @@ end @test centroid(poly) == cart(0.5, 0.5) # single vertex access - poly = PolyArea(cart.([(0, 0), (1, 0), (1, 1), (0, 1)])) + outer = cart.([(0, 0), (1, 0), (1, 1), (0, 1)]) + hole1 = cart.([(0.2, 0.2), (0.4, 0.2), (0.4, 0.4), (0.2, 0.4)]) + hole2 = cart.([(0.6, 0.2), (0.8, 0.2), (0.8, 0.4), (0.6, 0.4)]) + poly = PolyArea([outer, hole1, hole2]) @test vertex(poly, 1) == cart(0, 0) + @test vertex(poly, 2) == cart(1, 0) + @test vertex(poly, 3) == cart(1, 1) @test vertex(poly, 4) == cart(0, 1) + @test vertex(poly, 5) == cart(0.2, 0.2) + @test vertex(poly, 6) == cart(0.4, 0.2) + @test vertex(poly, 7) == cart(0.4, 0.4) + @test vertex(poly, 8) == cart(0.2, 0.4) + @test vertex(poly, 9) == cart(0.6, 0.2) + @test vertex(poly, 10) == cart(0.8, 0.2) + @test vertex(poly, 11) == cart(0.8, 0.4) + @test vertex(poly, 12) == cart(0.6, 0.4) + @test_throws BoundsError vertex(poly, 13) + # type stability + @inferred vertex(poly, 4) + @inferred vertex(poly, 8) + @inferred vertex(poly, 12) # point in polygonal area outer = cart.([(0, 0), (1, 0), (1, 1), (0, 1)]) From 103e1d15ccbc73d8a914e56c203cc7dc8c35a57e Mon Sep 17 00:00:00 2001 From: Elias Carvalho Date: Mon, 18 Nov 2024 17:48:02 -0300 Subject: [PATCH 2/4] Update 'vertextest' --- test/testutils.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testutils.jl b/test/testutils.jl index 9fbcf8f90..26c233dcf 100644 --- a/test/testutils.jl +++ b/test/testutils.jl @@ -183,9 +183,9 @@ function eachvertexalloc(g) end end -function vertextest(g; bytes=0) +function vertextest(g) @test collect(eachvertex(g)) == vertices(g) - @test eachvertexalloc(g) ≤ bytes + @test eachvertexalloc(g) == 0 # type stability @test isconcretetype(eltype(vertices(g))) @inferred vertices(g) From 5d7ebf675ee2d433705c3e9ffd53f8114a4c7513 Mon Sep 17 00:00:00 2001 From: Elias Carvalho <73039601+eliascarv@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:03:05 -0300 Subject: [PATCH 3/4] Update src/geometries/polytopes/polyarea.jl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Júlio Hoffimann --- src/geometries/polytopes/polyarea.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/geometries/polytopes/polyarea.jl b/src/geometries/polytopes/polyarea.jl index 9c4d515d2..a46558d6e 100644 --- a/src/geometries/polytopes/polyarea.jl +++ b/src/geometries/polytopes/polyarea.jl @@ -34,11 +34,11 @@ Base.isapprox(p₁::PolyArea, p₂::PolyArea; atol=atol(lentype(p₁)), kwargs.. function vertex(p::PolyArea, ind) offset = 0 for r in p.rings - offset′ = offset - offset += nvertices(r) - if ind ≤ offset - return vertex(r, ind - offset′) + nverts = nvertices(r) + if ind ≤ offset + nverts + return vertex(r, ind - offset) end + offset += nverts end throw(BoundsError(p, ind)) end From ffc3bc36b66142505620cb8535a61b6ad619915a Mon Sep 17 00:00:00 2001 From: Elias Carvalho Date: Mon, 18 Nov 2024 18:04:51 -0300 Subject: [PATCH 4/4] Update 'vertices' of 'PolyArea' --- src/geometries/polytopes/polyarea.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometries/polytopes/polyarea.jl b/src/geometries/polytopes/polyarea.jl index a46558d6e..4980b9f91 100644 --- a/src/geometries/polytopes/polyarea.jl +++ b/src/geometries/polytopes/polyarea.jl @@ -43,7 +43,7 @@ function vertex(p::PolyArea, ind) throw(BoundsError(p, ind)) end -vertices(p::PolyArea) = mapreduce(vertices, vcat, p.rings) +vertices(p::PolyArea) = collect(eachvertex(p)) nvertices(p::PolyArea) = mapreduce(nvertices, +, p.rings)