Skip to content

Commit

Permalink
CSharp Performance: when reusing clipper objects, currently clipper s…
Browse files Browse the repository at this point in the history
…ets the internal lists capacity, even if the capacity already sufficient. This causes C# to drop the currently allocated array and create a new, smaller one. (AngusJohnson#750)

This changes check if the capacity is sufficient before setting it to reduces allocations.
  • Loading branch information
SebastianDirks authored Dec 19, 2023
1 parent be61c7e commit 2d7564f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
23 changes: 15 additions & 8 deletions CSharp/Clipper2Lib/Clipper.Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,19 @@ internal static void AddLocMin(Vertex vert, PathType polytype, bool isOpen,
minimaList.Add(lm);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void EnsureCapacity<T>(this List<T> list, int minCapacity)
{
if(list.Capacity < minCapacity)
list.Capacity = minCapacity;
}

internal static void AddPathsToVertexList(Paths64 paths, PathType polytype, bool isOpen,
List<LocalMinima> minimaList, List<Vertex> vertexList)
{
int totalVertCnt = 0;
foreach (Path64 path in paths) totalVertCnt += path.Count;
vertexList.Capacity = vertexList.Count + totalVertCnt;
vertexList.EnsureCapacity(vertexList.Count + totalVertCnt);

foreach (Path64 path in paths)
{
Expand Down Expand Up @@ -800,7 +807,7 @@ protected void Reset()
_isSortedMinimaList = true;
}

_scanlineList.Capacity = _minimaList.Count;
_scanlineList.EnsureCapacity(_minimaList.Count);
for (int i = _minimaList.Count - 1; i >= 0; i--)
_scanlineList.Add(_minimaList[i].vertex.pt.Y);

Expand Down Expand Up @@ -2982,8 +2989,8 @@ protected bool BuildPaths(Paths64 solutionClosed, Paths64 solutionOpen)
{
solutionClosed.Clear();
solutionOpen.Clear();
solutionClosed.Capacity = _outrecList.Count;
solutionOpen.Capacity = _outrecList.Count;
solutionClosed.EnsureCapacity(_outrecList.Count);
solutionOpen.EnsureCapacity(_outrecList.Count);

int i = 0;
// _outrecList.Count is not static here because
Expand Down Expand Up @@ -3089,7 +3096,7 @@ protected void BuildTree(PolyPathBase polytree, Paths64 solutionOpen)
polytree.Clear();
solutionOpen.Clear();
if (_hasOpenPaths)
solutionOpen.Capacity = _outrecList.Count;
solutionOpen.EnsureCapacity(_outrecList.Count);

int i = 0;
// _outrecList.Count is not static here because
Expand Down Expand Up @@ -3354,10 +3361,10 @@ public bool Execute(ClipType clipType, FillRule fillRule,
ClearSolutionOnly();
if (!success) return false;

solutionClosed.Capacity = solClosed64.Count;
solutionClosed.EnsureCapacity(solClosed64.Count);
foreach (Path64 path in solClosed64)
solutionClosed.Add(Clipper.ScalePathD(path, _invScale));
solutionOpen.Capacity = solOpen64.Count;
solutionOpen.EnsureCapacity(solOpen64.Count);
foreach (Path64 path in solOpen64)
solutionOpen.Add(Clipper.ScalePathD(path, _invScale));

Expand Down Expand Up @@ -3394,7 +3401,7 @@ public bool Execute(ClipType clipType, FillRule fillRule, PolyTreeD polytree, Pa
if (!success) return false;
if (oPaths.Count > 0)
{
openPaths.Capacity = oPaths.Count;
openPaths.EnsureCapacity(oPaths.Count);
foreach (Path64 path in oPaths)
openPaths.Add(Clipper.ScalePathD(path, _invScale));
}
Expand Down
6 changes: 3 additions & 3 deletions CSharp/Clipper2Lib/Clipper.Offset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private void ExecuteInternal(double delta)
{
_solution.Clear();
if (_groupList.Count == 0) return;
_solution.Capacity = CalcSolutionCapacity();
_solution.EnsureCapacity(CalcSolutionCapacity());

// make sure the offset delta is significant
if (Math.Abs(delta) < 0.5)
Expand Down Expand Up @@ -257,7 +257,7 @@ public void Execute(DeltaCallback64 deltaCallback, Paths64 solution)

internal static void GetMultiBounds(Paths64 paths, List<Rect64> boundsList)
{
boundsList.Capacity = paths.Count;
boundsList.EnsureCapacity(paths.Count);
foreach (Path64 path in paths)
{
if (path.Count < 1)
Expand Down Expand Up @@ -545,7 +545,7 @@ private void BuildNormals(Path64 path)
{
int cnt = path.Count;
_normals.Clear();
_normals.Capacity = cnt;
_normals.EnsureCapacity(cnt);

for (int i = 0; i < cnt - 1; i++)
_normals.Add(GetUnitNormal(path[i], path[i + 1]));
Expand Down

0 comments on commit 2d7564f

Please sign in to comment.