How to accelerate the computing speed? (cluster : C#+ZombieSolver)

Hi, I am building my own cluster with several C# components and a “ZombieSolver” from Kangaroo2. The primary purpose is to delete the repeated mesh face from the cluster input.

I know the C# component probably causes the heavy computing part. Here is my code. I wonder how I can make it as faster as possible. Are there any ways to activate the GPU in the C# code?

/
/
/
/
(one of the recent tries takes 1.7HR to finish the algorithm) (the cluster)


/
/
/
/
/
(here is the c# part)

using System;
using System.Collections;
using System.Collections.Generic;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;



/// <summary>
/// This class will be instantiated on demand by the Script component.
/// </summary>
public class Script_Instance : GH_ScriptInstance
{
#region Utility functions
  /// <summary>Print a String to the [Out] Parameter of the Script component.</summary>
  /// <param name="text">String to print.</param>
  private void Print(string text) { /* Implementation hidden. */ }
  /// <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
  /// <param name="format">String format.</param>
  /// <param name="args">Formatting parameters.</param>
  private void Print(string format, params object[] args) { /* Implementation hidden. */ }
  /// <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj) { /* Implementation hidden. */ }
  /// <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj, string method_name) { /* Implementation hidden. */ }
#endregion

#region Members
  /// <summary>Gets the current Rhino document.</summary>
  private readonly RhinoDoc RhinoDocument;
  /// <summary>Gets the Grasshopper document that owns this script.</summary>
  private readonly GH_Document GrasshopperDocument;
  /// <summary>Gets the Grasshopper script component that owns this script.</summary>
  private readonly IGH_Component Component;
  /// <summary>
  /// Gets the current iteration count. The first call to RunScript() is associated with Iteration==0.
  /// Any subsequent call within the same solution will increment the Iteration count.
  /// </summary>
  private readonly int Iteration;
#endregion

  /// <summary>
  /// This procedure contains the user code. Input parameters are provided as regular arguments,
  /// Output parameters as ref arguments. You don't have to assign output parameters,
  /// they will have a default value.
  /// </summary>
  private void RunScript(Mesh MeshToReduce, ref object Deleted_Faces, ref object ReducedMesh)
  {

    Mesh m = new Mesh();//temperory mesh for adjustment in the algorithm
    m = MeshToReduce;

    int faceCount = m.Faces.Count;
    Print("The original Mesh Face Count = " + faceCount.ToString());
    //int[] faceID = new int[faceCount];
    List<int> faceID = new List<int>();
    Point3d[] faceCenter = new Point3d[faceCount];
    //fill-in faceID and faceCenter

    for(int i = 0 ; i < faceCount ; i++)
    {
      faceID.Add(i);
    }

    //List<int> Facelist = m.Faces;
    List<int> DeleteFaceID = new List<int>();


    for(int i = 0 ; i < faceCount ; i++)
    {
      Point3d CurrentFaceCenterPt = m.Faces.GetFaceCenter(i);


      for(int j = 0 ; j < faceCount ; j++)
      {
        bool status = false;
        for(int k = 0 ; k < DeleteFaceID.Count ; k++){
          //
          if (i == DeleteFaceID[k]) status = true;

        }

        if( status ) break;

        if( i == j ) continue;

        /*
        if(CurrentFaceCenterPt.DistanceTo(m.Faces.GetFaceCenter(j)) < 0.01 || CurrentFaceCenterPt.DistanceTo(m.Faces.GetFaceCenter(j)) == 0)
        {
          DeleteFaceID.Add(j);//int
          DeleteFaceID.Add(i);//int
        }
        */

        if(CurrentFaceCenterPt.DistanceTo(m.Faces.GetFaceCenter(j)) < 0.01 || CurrentFaceCenterPt.DistanceTo(m.Faces.GetFaceCenter(j)) == 0)
        {
          DeleteFaceID.Add(j);//int
          DeleteFaceID.Add(i);//int
        }
      }
    }

    Deleted_Faces = DeleteFaceID;

    m.Faces.DeleteFaces(DeleteFaceID);//removed Faces that is duplicated

    Print("The reduced Mesh Faces Count = " + m.Faces.Count);

    ReducedMesh = m; //ouput

  }

  // <Custom additional code> 

  // </Custom additional code> 
}```

You should supply a gh file with internalized inputs if you want help.

        for(int k = 0 ; k < DeleteFaceID.Count ; k++){
          //
          if (i == DeleteFaceID[k]) status = true;

        }

You should probably break from this loop after setting status to true.

It also appears you are doing some needless looping with j & k.

I would put everything inside a do while loop, and inside there you should start the loop from a list of faces that doesn’t contain the deleted faces. If you start off with 1000 faces, and removing 1 or more on each iteration, what’s the point of iterating through all faces again and again?