GH Python Script Execution Time Increases On Each Successive Run

I have a script that works on individual planar curves and creates hundreds of offset curves with Rhino.Geometry. This is done in an ghpython component, that imports custom python classes. Results are great.

On one curve the script has an acceptable runtime of approx. 10-12 s depending on the inputs.

However this has to be applied to 100 - 200 curves, thus I would like to batch run it for 1 hour and be done with it.

Unfortunately the execution time increases from 10s on the first run, to 20s on the 2nd and so forth. So I can only process really small batches in an acceptable time frame. If I loop over too many curves Rhino becomes unresponsive and the risk of crashing is increased.

It does not matter whether:

  1. I feed the curves as a list access / array and loop over the curves within the python component
  2. I design the component for a single curve and then use implicit looping via “item access” and feed the curves as array.

Runtime/behaviour is almost identical.

I looked for bottlenecks or growing arrays in the code, but just the smallest operations take longer and longer on each subsequent run. e.g. 50 ms to 100 ms to 150 ms.

The heavy lifting is done in Rhino.Geometry with Offsets of NurbsCurves, PolyCurves, Trimming and Joining results etc.

Is there any way to reset and free rhino python ressources within the loop to avoid this behaviour?

The topic has been brought up here, but that is from 2014 and I am not sure that is still an issue:

https://www.grasshopper3d.com/m/discussion?id=2985220%3ATopic%3A997897

BR Conrad

For the record: Win11, RH8 SR10 (most recent), python 3 scipts used.

I ran another test ran a different calculation once in the Script Editor & GH Python component. I I ran a method of my objects in the loop for about 600 times. Then I timed the execution time for each operation. See the results below.

Clearly the ghpython execution time seems to increase within the loop, making it prohibitive to use on large loops. In script editor execution seems to be constant.

Anybody can reproduce this as well with their codes?

Nope. You’ll probably need to post some code that demonstrates the issue for any meaningful feedback. Also, there appears to be some confusion about which component is showing this behaviour (i.e. GHPython, the new IronPython, or the new CPython component), which a minimal (non-)working example file would also help clarify.

@cpbln Would you mind running this test on 8.11 SRC as well? It would be great to have a chart for comparison.

No change with SRC 8.11. Behaviour is the same.

Unfortunately I am working with IP related geometry and code so I cannot post the problem as is. I am trying to produce a minimal working example.

I created a simple example, where the behaviour from running the python 3 code from the script editor really differs from the GH python 3 component.

For two curves (top, bottom) points along the x axis are determined on a linear spaced grid. This is done with a world yz plane intersecting with each curve and determining the intersection points.

One iteration takes 40 ms on my machine, that is constant in the python script, no matter how many loops I run (e.g. up to 1000).

In ghPython3 the speed is the same on low number of loops (e.g. 10 or 100). But If I increase to 1000 loops or beyond the runtime increases by factor 3 or 4 towards the end. Also memory consumption seems to rise drastically.

I am not looking for an improvement for this specific code, but understand how to make sure GHpython iteration runtimes show the same behaviour as running a py3-script directly.

Curve_Plane_Intersections_GH_Py3_Speed_issue.3dm (81.2 KB)
Rhino_v8_speed_test.gh (4.3 KB)
Rhino_v8_speed_test.py (1.6 KB)

@cpbln So I tested the 3dm and scripts that you shared here in latest Rhino 8.11. Here is what I am seeing:

I ran the script and definition multiple times and pretty much see similar numbers. Memory consumption is also fairly stable (not rising at an alarming rate) but I know this is a simplified example so you are probably seeing this differently.

Replicating the Issue

Not sure what am I missing on this test. I would be nice to run this test on a clear Rhino (no plugins) on your machine just to make sure other factors are excluded.

Python 3 Performance

To answer your question above, Python 3 performance in both GH and Rhino should be the same. There is a little fluff that Grasshopper component does for managing the input/outputs and execution context that affects the exec time of the component but the overhead should be very small.

Note that Python 3 is running inside of dotnet environment and under current implementation (fork of pythonnet), accessing dotnet properties and methods (e.g. rg.Intersect.Intersection.CurvePlane) are much slower than IronPython. The rest of python 3 (anything not dealing with dotnet) should run as fast as python 3 normally runs.

Hi Ehsan,

Thanks for looking into it. It seems you are getting the results I am looking for. Good to know it works as intended for you. Just predictable runtime that scales with the number of iterations. Just like in python 3 scripts.

However I have two machines with identical hardware side by side and they both produce a different behaviour towards the higher iteration numbers:

  1. one fast iteration (30 - 50 ms)
  2. 5 (sometimes 4) slower iterations 100 ms

Both are Dell Precision M7530, 6 core machine ( i7-8850H CPU @ 2.60GHz ).
This is just with stock Rhino (no special plug-ins, other than pandas, numpy, scipy).

Hi Ehsan,
Strangely enough this problem is solved on 3 different machines within the last 2-3 hours without changing any code or different installations. I can now run 2000 iterations with more or less constant runtimes per iteration.

Thus I believe it must be related to some Windows 11, company software or driver install that was pushed company wide. I noticed that a .NET framework update for Win11 was installed, as well as some other updates.

Unfortunately I cannot pin-point the origin of the problem. But thank you for confirming that the problem is not within Rhino & Grasshopper.

1 Like

Anytime. Makes me happy that I don’t have some bad code slowing things down in Rhino :sweat_smile:

Keep me posted on the progress and new findings. My main focus right now is maturing the new scripting environment in Rhino 8, so more features can be built on top of this in 9.x and GH2

3 Likes