Python Optimization in TouchDesigner

We all love using Python in TouchDesigner. It gives you so much flexibility and power to create whatever you want. But I’m sure you’ve heard all the pros say “be careful! Python can get real slow!” While this is true, it doesn’t mean that there aren’t easy ways to optimize your Python usage so you can get both power and performance together. These tricks are a summary of a handful of discussions we’ve had in The HQ PRO and many of insights come from Matthew Ragan, who’s been diving in with everyone on the Python goodness. Let’s dive in!

Accessing Objects

The first thing to know about Python is that it’s actually pretty fast. It’s not inherently slow for executing commands or doing its own calculations. What does get slow quickly though is accessing TouchDesigner objects through Python. What does this mean? Think about every time time you call an op() search or every time you go to update a parameter. These are the parts of the script that end up being the most slow for folks. So what are some ways to optimize this quickly?

The first is to reduce your op calls and searches. Instead of doing something like this:

a = op('some_op').par.value0
b = op('some_op').par.value1
c = op('some_op').par.value2

You could instead do this:

some_op = op('some_op').par
a = some_op.value0
b = some_op.value1
c = some_op.value2

Now this is obviously an oversimplified example, but it makes a simple point. Why do three OP searches, access the parameter class three times, and then access the values? Instead we can access the operators parameter class once, then just access the values from that. In a small script like this, you’ll never notice a difference. But once you start get bigger and bigger scripts, extensions, or callbacks that are firing regularly (or every frame), then these gains start to compound.

Code placement in Callbacks

Another nifty trick that Matthew demonstrated was making improvements to your code by placing elements in more optimal positions in your callbacks. For example if you have some code like this in a callback:

While this may seem like the normal way to do this, you might not realize that every time those values are changing you’re re-initiating all 4 op() calls. So instead what you can do is move those outside of the callback, so that the callback being triggered on every value change only executes the if statement and doesn’t recall the op() call over and over again:

As you start to get into bigger and bigger callback scripts, little things like this can greatly add up on the savings.

Don’t spam the textport

This one is a simpler one that a lot of new folks never think about and more experienced users sometimes forget. It’s simple: don’t spam the textport. The longer and longer the textport log gets, the slower your project will run. If you want to see this in action, open up the textport, drop an Execute DAT into your project, and just print(‘hello’) on every frame start. In a matter of seconds you’ll quickly start to see your frame rate plummet until you hit the Clear button on the textport to clear it. The best thing to do is keep track of print statements in your project and turn them off before you get to your final deployment.

Wrap up

Python in TouchDesigner is probably one of the most useful skills you can add to your tool kit. Even if you hear pros saying “Be careful, Python can be slow!” that means they’re still using it, just in an optimized fashion. These tricks should help get you the maximum performance for your projects while still letting you take advantage of Python all along the way.