Is Rhino 8 C# really slow?


Just tried rebuilding a Rhino 7 C# component in Rhino 8 C#. It is really slow. Anyone know why? R7 is at the top (43ms), the R8 is at the bottom (227ms)

The code is:

private void RunScript(double x, double y, ref object rect, ref object joined)

    if (x.GetHashCode() == 0) x = 200;
    if (y.GetHashCode() == 0) y = 200;

    x *= 0.5;
    y *= 0.5;

    Point3d[] pts = {
      new Point3d(-x, -y, 0),
      new Point3d(-x, y, 0),
      new Point3d(x, y, 0),
      new Point3d(x, -y, 0)

    GH_Line[] line = {
      new GH_Line(new Line(pts[0], pts[1])),
      new GH_Line(new Line(pts[1], pts[2])),
      new GH_Line(new Line(pts[2], pts[3])),
      new GH_Line(new Line(pts[3], pts[0]))

    rect = line;
    joined = new Polyline(new[] {pts[0], pts[1], pts[2], pts[3], pts[0]});

Any suggestions very welcome!!


Because I (we?) don’t know exactly how Grasshopper structures its calls and timings (when the clock starts, possible threading, etc.), I’d be tempted to do two separate runs, one with the old control only and one with the new control only.

Good idea. Just tested: In the two separate runs R8 was 188ms R7 was 40ms. (This was running both in Rhino 8)

Not sure, I know that GetHashCode is one of the major changes of Net4.8 to newer Net. It produced some headaches when migrating my apps some years ago. Its one of the few functions which are slower. In newer Net, the hash-code is different on each runtime which is a security feature. Could you remove it, and compare again?

Both the old and new scripting components are running under the same framework. We’ll need to test to figure out why there would be any difference at all.

1 Like

Hi Tom,

That’s really interesting. I tried removing the GetHashCode and it didn’t have any effect. By the way, is there a better way to find out if the Script component has something plugged into it that using GetHashCode? It’s a bit of a hack from my side.


Hi Steve,

Thanks for looking in to this. I have a feeling that whatever is causing the slow down in R8 C# components is also the reason that some files won’t open and kill Rhino.

Any pointers on what it could be would be fantastic.


(BTW the R7 C# component runs faster in Rhino 8 than Rhino 7 - ~40ms vs ~60ms, just not the R8 C# component)


Good to know!

Although the R8/GH script editor is somewhat nice to use, there’s also something going on in the background (pre-compiling?) which slows down the editing.

So, something is constantly causing “lag” when coding. And worst of all, the component sends data to the outputs while modifying code, triggering the entire downstream GH definition, which of course stops the editor from responding until the whole definition is calcuated and… :grimacing:

@stevebaer might have ideas about why all this is happening?

Anyway, hopefully that can be fixed soon, otherwise I see no other way to handle it than to resort to copying a R7 C#-Script Component from a R7 “template file” and use that in my R8 GH definitions.

If editing code triggers slow updates when the code changes and results in different outputs that get sent downstream during edits, then my first thought at a workaround would be to, when editing code, first add a return at the very beginning such that it returns nothing*, ever, regardless of what edits I’m making in the code body.

Hopefully other components don’t rerun their outputs when the inputs haven’t changed even when the component being edited says “The guy at the keyboard typed something. Here’s the empty set… again”.

*or some other convenient but constant result

Problem is that this is part of the code validation, An error is shown if not all “return paths” are assigned, like when you forget to assign a value to an out parameter (which the outputs actually are). So that won’t work (except for sending nulls to outputs that would accept it).


You got me on the out parameters, but that’s just another assignment per parameter before the return, right? It’s not that much different from intentionally exiting (but not throwing an error) when you find a special condition.

//the rest of the stuff in the function

True, but during development I often have a whole bunch of “debug outputs” and dealing with all that takes too much time and messes up the code, only to prevent recalculation.

Look at this horrible although very useful example of “debug ouputs”… :

I wonder if there’s a keyboard shortcut to disable the script component, and then quickly enabling it again when recompilation is desired… that could be something… perhaps. I’ll try that.


It sounds like we’ve split off to a different topic of performance while editing versus runtime performance. @eirannejad has really taken the lead on this project in Rhino 8, but he’s pretty busy this week on a business trip.

I’m pretty sure we can match runtime performance for the older script components with the new ones. We’ll need to do a little more digging.

1 Like

FWIW, one can still unhide/instantiate C# and GHPython components in Rhino 8, while the new script editor gets functional parity. See this topic for two approaches (i.e. make user objects and/or search with the # prefix):


Thank you for the #Hint# ! It will become very useful! :smiley:


1 Like

3 posts were split to a new topic: Script Parasite in Rhino 8

@Ashley_Cichocki Are you using the old C# component on the new Script component started with C# script?

Hi @eirannejad I opened a new Rhino 8 GH file and pasted a Rhino 7 component in, then added a Rhino 8 Script component and put the same code into that.

My original goal was to start to rebuild all my old Rhino 7 C# script components in Rhino 8 that’s when I first saw the problem.

Okay I created this ticket and will get it resolved. There must be something happening there that is slowing down the exec

RH-78353 Improve script component exec performance


Thanks @eirannejad . Just tried SR3 and the speed between the old C# and the Script components in Rhino 8 are the same, and they are both faster than in Rhino 7.

1 Like