Hey @christopher6

Off the top of my head a few things that would make this slow:

- The component executes the same number of times that there are mesh vertices
- The component needs to output the number of curves * the number of vertices points
- Even though each check is exclusive, they are run in parallel

Other improvements could be using a spatial data structure (4) (KD-Tree or OcTree) to remove the need for each point to check each curve, but let’s try without first.

To reduce (1), using a C# component with list/list access (rather than the default component which has item/list access) should be much faster.

To reduce (2), we can only output the data needed by performing some sorting in the component. In addition to this, we can cast directly to the type we need as the GH cast mechanisms are a little slow.

And for (3) we can perform it in parallel.

###
Implementing (1) and (2)

As a C# component

```
private void RunScript(List<Point3d> points, List<Curve> curves, ref object distance)
{
List<GH_Number> results = new List<GH_Number>();
foreach (Point3d p in points)
{
double closestDistance = double.MaxValue;
foreach (Curve c in curves) {
double param;
if (c.ClosestPoint(p, out param)) {
double dist = c.PointAt(param).DistanceTo(p);
if (dist < closestDistance) {
closestDistance = dist;
}
}
}
results.Add(new GH_Number(closestDistance));
}
distance = results;
}
```

**2 Curves** about 10-15% faster

**5 Curves** about 25-30% faster,

###
Implementing (3): running in parallel

A slight refactoring to use arrays and indexing the points lets us run in parallel

```
private void RunScript(List<Point3d> points, List<Curve> curves, ref object distance)
{
GH_Number[] results = new GH_Number[points.Count];
System.Threading.Tasks.Parallel.For(0, points.Count, (index) => {
Point3d p = points[index];
double closestDistance = double.MaxValue;
foreach (Curve c in curves) {
double param;
if (c.ClosestPoint(p, out param)) {
double dist = c.PointAt(param).DistanceTo(p);
if (dist < closestDistance) {
closestDistance = dist;
}
}
}
results[index] = new GH_Number(closestDistance);
});
distance = results;
}
```

**2 Curves** about 2x faster

**5 Curves** about 5x faster,

**120 curves** about **40x** faster!

##
Discussion

So computing multiple curves takes a similar amount of time to computing a singular one as we distribute the load across multiple threads. This ends up diminishing slightly when we are computing for more curves than we have processor threads, which is why we see a 1:1 improvement with 5 curves, but a 1:3 improvement with 120 curves.

On my Ryzen 9 3900X (12 core/24 thread) these are results for comparison with the base Curve CP component:

Plus we can then remove the expensive sorting that comes after (another 20s).

About **40x** faster (due to (1) (2) and (3) not just the multithreading!

Attached:

210904_test script_cn.gh (11.4 KB)