# Which approach is most appropriate - writing python code

**URL:** <https://discourse.mcneel.com/t/which-approach-is-most-appropriate-writing-python-code/75556>\
**Category:** Grasshopper\
**Tags:** grasshopper, python\
**Created:** [November 29, 2018, 3:28pm UTC](https://discourse.mcneel.com/t/which-approach-is-most-appropriate-writing-python-code/75556 "2018-11-29T15:28:11Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![charles2](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/charles2/32/296662_2.png) [@charles2](https://discourse.mcneel.com/u/charles2)\
**Post date:** [November 29, 2018, 3:28pm UTC](https://discourse.mcneel.com/t/which-approach-is-most-appropriate-writing-python-code/75556/1 "2018-11-29T15:28:11Z")

</div>

I’ve been writing a few python scripts now again but I’ve never questioned which package is most appropriate to use until I came across two different approaches to generate curves from text with a big difference in calculation time.

The first example with Rhino is very fast to compute - 45ms:

```
import Rhino as rc

preText = rc.RhinoDoc.ActiveDoc.Objects.AddText(text, location, text_height, font, True, False)

postText = rc.RhinoDoc.ActiveDoc.Objects.Find(preText)

textCrvs = postText.Geometry.Explode()

rc.RhinoDoc.ActiveDoc.Objects.Delete(postText, True)

crvs = textCrvs

```

However, the second example with rhinoscriptsyntax takes forever at 2.6s:

```
import rhinoscriptsyntax as rs

geoList = []

preText = rs.AddText(text, plane, height, font)
textGeo = rs.ExplodeText(preText, True)

for i in textGeo: geoList.append(rs.coercegeometry(i))

for i in textGeo: rs.DeleteObject(i)

```

Can someone clarify what’s going on? How does one decide to use Rhino vs Rhinoscriptsyntax?

[text2curve.gh](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/8/c/8ca094bfc49e5924e01e276d91ae0e2b57ed4538.gh) (6.9 KB)

---

<div class="post-metadata">

**Author:** ![piac](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/piac/32/769366_2.png) [@piac](https://discourse.mcneel.com/u/piac)\
**Post date:** [November 29, 2018, 3:59pm UTC](https://discourse.mcneel.com/t/which-approach-is-most-appropriate-writing-python-code/75556/2 "2018-11-29T15:59:43Z")

</div>

Most time is actually spent redrawing. It takes time to redraw the document. Some time is spent also creating the Undo-Redo operations.

This script requires to add objects to the Rhino document, because there is no [TextEntity](https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_TextEntity.htm) in GhPython. This might be added in the future, especially once Grasshopper itself will support formatted text as geometry, but for now, this is what we have.

So I added:  
`sc.doc = Rhino.RhinoDoc.ActiveDoc` to set up the target document and  
`sc.doc = ghdoc #required` at the end to make up for the changed setup.

Also, I added:  
`rs.EnableRedraw(False)` to remove redrawing and  
`rs.EnableRedraw(True)` at the end to re-enable redraw.

With these changes, the script is still slower with RhinoScript, but by a smaller amount.

[text2curve\_fixed.gh](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/3/8/38e465f7fffd40a001909e4777d865cfca9af887.gh) (11.8 KB)

I also removed a few lines that are not required in the RhinoScript counterpart.  
Overall, this particular sample is not so great in RhinoScript, because you always need to target the Rhino document and that is particularly slow. We added the `ghdoc` exactly to mitigate this slowdown.

Thanks,

Giulio

–  
Giulio Piacentino  
for Robert McNeel & Associates  
[giulio@mcneel.com](mailto:giulio@mcneel.com)

---

<div class="post-metadata">

**Author:** ![axa](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/axa/32/763862_2.png) [@axa](https://discourse.mcneel.com/u/axa)\
**Post date:** [November 29, 2018, 4:00pm UTC](https://discourse.mcneel.com/t/which-approach-is-most-appropriate-writing-python-code/75556/3 "2018-11-29T16:00:00Z")

</div>

You don’t need rs.coercegeometry(), at least not when you run it in Rhino (not sure about GH)

Also, you don’t need the geoList.

Try this:

```auto
import rhinoscriptsyntax as rs

preText = rs.AddText(text, plane, height, font)
textGeo = rs.ExplodeText(preText, True)

rs.DeleteObjects(textGeo )

```

If you do need to make a new list, use list comprehension like so:

```auto
geoList = [i for i in textGeo]

```

---

<div class="post-metadata">

**Author:** ![charles2](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/charles2/32/296662_2.png) [@charles2](https://discourse.mcneel.com/u/charles2)\
**Post date:** [November 30, 2018, 9:36am UTC](https://discourse.mcneel.com/t/which-approach-is-most-appropriate-writing-python-code/75556/5 "2018-11-30T09:36:16Z")

</div>

Thanks for the clarification Guilio, I have a few more questions.

rhinoscriptsyntax is still ~8x slower but if I understand correctly this is only becuase GH doesn’t contain a native Text type? Otherwise, for most other cases it should be just as fast?

`sc.doc = ghdoc` - why is this required?

Lastly, have I missed a document/article on best practices for python within GH?

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [November 30, 2018, 10:25am UTC](https://discourse.mcneel.com/t/which-approach-is-most-appropriate-writing-python-code/75556/6 "2018-11-30T10:25:22Z")

</div>

> [@charles2](#):
>
> Otherwise, for most other cases it should be just as fast?

No, they will generally be slightly slower to some extent. This becomes especially noticeable when making many computations, as demonstrated/discussed here:

> **[How to input and use point in GhPython directly?](https://www.grasshopper3d.com/forum/topics/how-to-input-and-use-point-in-ghpython-directly?commentId=2985220%3AComment%3A1718054)**
>
> Hey, 
> I am a beginner of GhPython.
> I want to use the points from grasshopper directly, but I cannot.
> I guess there must be some ways to declare x should be a p…

> [@charles2](#):
>
> Lastly, have I missed a document/article on best practices for python within GH?

There are some great bits here:

> **[Rhino.Python Guides](https://developer.rhino3d.com/guides/rhinopython/)**
>
> Quickly add functionality to Rhino or automate repetitive tasks.

Unfortunately a lot of the nitty-gritty best practices are floating around this and the old Grasshopper forum. Specific to performance, there’s a bunch of nuggets to be found here (specifically how setting type-hints on inputs, and wrapping outputs can speed things up):

> **[GHPython Some Bottlenecks (Bugs?)](https://www.grasshopper3d.com/forum/topics/ghpython-some-bottlenecks-bugs)**
>
> Hi Giulio and Steve, I've recently noticed a couple of bottleneck with the GHPython component which can quite severely impede on performance. Thought I would…

Also, always be profiling your code within the GHPython component, to get a more accurate diagnosis of where precisely your bottlenecks are. I tend to use simple classes such as this one for profiling:

```python

import time

class Timer(object):
    
    """ A simple profiler """
    
    def start(self):

    	# Start the timer
        self.startTime = time.time()
        
    def stop(self):
        
        # Print and return elapsed time
        elapsedSeconds = time.time() - self.startTime
        elapsedMilliseconds = elapsedSeconds*1000
        print str(round(elapsedMilliseconds,3)) + " ms"
        return elapsedMilliseconds

```

---

<div class="post-metadata">

**Author:** ![piac](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/piac/32/769366_2.png) [@piac](https://discourse.mcneel.com/u/piac)\
**Post date:** [November 30, 2018, 12:10pm UTC](https://discourse.mcneel.com/t/which-approach-is-most-appropriate-writing-python-code/75556/7 "2018-11-30T12:10:55Z")

</div>

> [@charles2](#):
>
> rhinoscriptsyntax is still ~8x slower but if I understand correctly this is only becuase GH doesn’t contain a native Text type? Otherwise, for most other cases it should be just as fast?

For cases where you actually work in “high-level”, RhinoScriptSytanx is generally just as fast as RhinoCommon, because the long calculation happens anyways in C++ in the Rhino core… think for example of Boolean intersections, extruding things, moving large objects.

For math-like operations, probably this scale of performances will help you:

```plaintext
assembly < C/C++ < C#/Vb.Net < Python:RhinoCommon < Python:rhinoscriptsyntax

```

Somewhere from `C#/Vb.Net` to after `IronPython:rhinoscriptsyntax`, there’s programming in `Grasshopper components`, depending from what you are doing.

Of course there are exceptions, but this is more or less the state of things. The closer you are to the hardware, the more you can squeeze… but is it really worth it? It will also take much longer to write the same things.

Also, often the real bottleneck is not the performance on the language level, but the right choice of algorithm. An O^2 algorithm will take around 1’0000 times longer to compute for just 32 times the size of input, etc.

> [@charles2](#):
>
> Lastly, have I missed a document/article on best practices for python within GH?

The suggestion is to always program where you are most comfortable. We support all these environments so that you can find the right place for you.
