DataTree poulated with geometrical data in a loop results in significant slow down

Recently stumbled into an interesting effect in Grasshopper while developing a component for parametric definition of numerical models.
To easily access outputs of the code within the grasshopper I utilised DataTree structures.
I run into the performance issue where code was taking significantly longer than expected to generate geometry (NurbsSurfaces + Points3d). After some analysis I was surprised to find out that the majority of time > 95% was spend not on calculations but on storage of Rhino geometry entities within the DataTree structure.
Replacing DataTree with the nested List structure addresses the issue. It is curious to note that this slow down was only present for the geometric entities and not for the integer storage.

Mock code for this to occur:

for (int ii = 0; ii < num_1; ii++)
      `for (int jj= 0; jj< num_2; jj++)`
           for (int kk = 0; kk< num_3; kk++)
                List<NurbsSurface> vol_face = Vol_Face_Geom_Constr(some_inputs);
                GH_Path e_path = new GH_Path(ii, jj, kk);
                mesh3d_geom.AddRange(vol_face, e_path);

If anyone has any ideas what is occurring here, or even some workarounds, it would be nice if you could share you experience.

If your types can be cast to some equivalent GH_[Type] then it will be faster, and you can also use GH_Structure instead of Datatree. Tends to be (significantly) faster.

// Rolf

Thank you for the suggestion.
I just run a few tests with this.
It looks like DataTree Casts geometric data inside of it, as time for GH_Structure + Cast gives about the same performance as DataTree, while GH_Structure on its own (filled with Null objects) is faster.

I will probably modify my code to work with nested Lists, as it seems to be the fastest of the available options.

If you can use nested Lists it indicates that you used DataTree “internally” in your algorithm. Then yes, its much faster to use Lists. And if you know the number of elements in advance, then you can go for arrays and use Parallel.For in loops (arrays are thread safe).

In cases where I need DataTree or GH_Structure for complex output, I usually put the data into the Tree only after all the processing in the (component’s main) algorithm is all done.

// Rolf

1 Like