Dear experts,
I´m trying to extract a tree of lines as fast as possible from a C# component. In the DataTree documentation it is said that “If you’re using the Grasshopper SDK you should consider using the GH_Structure class instead.”
Since the number of lines could be huge, e.g. over 500000. In the following example I´ve used just around 45000 lines, but feel free to play with sliders to see how it affects performance. DumpLinesGH.gh (17.4 KB)
Using “Dump Mode” dropdown list you can switch between Line, Tree, GH_Line and GH_Goo alternatives. Whereas the times given by profiler are 230, 320, 80 and 50 ms, respectively, the Watch timer produces 2, 33, 25 and 30 ms. This indicates that a lot of work is being carried out outside the user introduced C# code. Basically, the four alternatives try to use:
List<Line> lines = genLines(pts); // Generate Lines
DataTree<Line> linesTree = new DataTree<Line>();
GH_Structure<IGH_Goo> gh_linesTree = new GH_Structure<IGH_Goo>();
GH_Structure<GH_Line> gh_linesTree = new GH_Structure<GH_Line>();
Unfortunately, despite all four data structures are able to allocate and use the Lines inside C# component, outside it is not possible when using a GH_Structure (red Line component).
What am I doing wrong? Any help is highly appreciated !!
PS: I´m sorry, I´m not an expert in C#… but I´ve tried (unsuccessfully) to follow what it is said here:
Perhaps pasting the code here helps:
private void RunScript(List<Point3d> Pts, int x, ref object Lines)
{
// Initialize some watches
var watch = new System.Diagnostics.Stopwatch();
var watch2 = new System.Diagnostics.Stopwatch();
watch2.Start();
GH_Path pth;
pts = Pts.ToArray(); // Convert List to Array (arrays are fastere)
watch = new System.Diagnostics.Stopwatch();
watch.Start();
List<Line> lines = genLines(pts); // Generate Lines
Print("Total Lines [#]: " + lines.Count);
watch.Stop();
Print("genLines: " + watch.ElapsedMilliseconds + " ms");
watch = new System.Diagnostics.Stopwatch();
watch.Start();
switch(x)
{
case 0:
Lines = lines;
break;
case 1:
DataTree<Line> linesTree = new DataTree<Line>();
pth = new GH_Path(0); // first path
for(int i = 0; i < lines.Count; i++)
{
pth = new GH_Path(i);
linesTree.Add(lines[i], pth);
}
Lines = linesTree;
break;
case 2:
GH_Structure<GH_Line> gh_linesTree = new GH_Structure<GH_Line>();
for(int i = 0; i < lines.Count; i++)
{
pth = new GH_Path(i);
GH_Line gh_line = new GH_Line(lines[i]);
gh_linesTree.Append(gh_line, pth);
}
Lines = gh_linesTree;
pth = new GH_Path(135);
Print("gh_linesTree--> " + gh_linesTree.get_DataItem(pth, 0));// [GH_Path, Int32]
break;
case 3:
GH_Structure<IGH_Goo> gh_gooTree = new GH_Structure<IGH_Goo>();
for(int i = 0; i < lines.Count; i++)
{
pth = new GH_Path(i);
GH_Line gh_line = new GH_Line(lines[i]);
gh_gooTree.Append(gh_line, pth);
}
Lines = gh_gooTree;
pth = new GH_Path(135);
Print("gh_gooTree--> " + gh_gooTree.get_DataItem(pth, 0));// [GH_Path, Int32]
break;
}
watch.Stop();
Print("Dump: " + watch.ElapsedMilliseconds + " ms");
watch2.Stop();
Print("Total time: " + watch2.ElapsedMilliseconds + " ms");
}
// <Custom additional code>
// GLOBALS
Point3d[] pts; // Convert List to Array (arrays are faster)
// GENERATE ALL POSSIBLE LINES (SEGMENTS) FOR GIVEN POINTS
List<Line> genLines(Point3d[] pts)
{
// Lines List Output
List<Line> lines = new List<Line>();
// Generate all possible lines (no directional)
for(int i = 0; i < pts.Length - 1; i++)
for(int j = i + 1; j < pts.Length; j++)
lines.Add(new Line(pts[i], pts[j]));
return lines;
}
// </Custom additional code>
}