Optimizing dynamo script

Hello experts,

I have made a Dynamo script which joins walls that are parallel to eachother, the script is working as intended but my main problem is; It takes tooooooooo long! The script literally takes around 2-3 minutes on a very small project with only 15 outer walls and more than 10-15 minutes on larger projects, making it seem like it’s faster to manually click the walls you want to join, even it is more than 50+ walls.
Does anyone have any tips or ideas how to make this script run faster?

JoiningElementsByLine(referentiewoning-test).dyn (49.3 KB)

Thank you in advance,

Selim

To get the best performance you need to:

  1. Re-write your script in C# (Visual Programming is inherently inefficient due to the high levels of redundancy which have to be accepted for it to function)
  2. Stick to the Revit API and avoid the ProtoGeometry library and any kind of geometry conversion or element wrapping between Revit and Dynamo.
2 Likes

It is also good to try and filter as much as possible. For instance, if it is only outer walls then filter for those wall types before doing any work on them.

The best way to reduce the computational time is to reduce the complexity of the problem space. You’re currently in N^n complexity space. Getting EVERY walls locations, finding the locations, finding the lengths, stuff, etc…

Testing EVERY wall’s location against EVERY OTHER wall’s location, building a curve from points, finding their direction, rotating it 90 degrees, creating a line from the start points, then joining as a result of each test. As @SeanP pointed out, reducing the data set to limit the number of tests is how you will see the most gain in speed, be the code written in C or Python or Design Script or just basic Dynamo nodes is secondary to that point.

Assuming exterior only walls (as @SeanP did), I would reduce scope in a series of steps:

  1. Get just the walls in the active view, or just the walls on a given level. On a 10 story building this would remove about 90% of the walls instantly, leaving you with n/10 as a start point.
  2. Group the walls by the façade’s bounding box. On a 4 sided building that reduces the scope to four sets of n/40.

This is kind of over simplifying it, but:
If the number of walls is 100, you currently have 100100, or 10,000 intersection tests.
The first reduction I show above simplifies it to 10 x 10 tests, or 100 intersection tests.
The second reduction simplifies it to 4
(2.5*2.5) tests, or 25 intersection tests.

There are some good courses to learn this from in the MIT open course-ware classes.

Beyond that, there are several things which could change in terms of efficiency after you reduce the scope. Translating your start point by [val,-val] and then using a Line.ByBestFitThroughPoints node would remove a lot of extra memory hits which you have - by my estimate you could reduce the number of functions by 6 or more. Leveraging some list levels and lacing could likely reduce the scope further - maybe another 2 functions down in the end.

All of that said, I’m not sure you’re actually testing what you want here, as it’s quite possible to have a non-intersecting wall which is 500 units (even assuming you’re working with MM?) away from the other wall. You might want to go test this in some other projects to be certain you aren’t adding any warnings around ‘joined elements do not touch’. Adding warnings along that line are going to slow things down exponentially no matter what you do.

Lastly, as @Thomas_Mahon mentioned, the other ‘long running’ nodes are going to mostly be around converting the data from Revit to Dynamo types, which are only avoidable by jumping from Dynamo to full blown Revit add-in via the API (which will require you to code more efficiently in the first place).

5 Likes

Thank you all for the tips, I have modified the script by adding “select model elements” to reduce the scope of the task greatly. The script runs within seconds now and is still working as intended. The options to re-write the script in programming language is still a no-go for me since I stepped into the world of Dynamo a few weeks ago and didn’t fully learn the programming languages yet.

Added the script for anyone willing to test/use it. Join_All_Elements_Of_Selected_Walls_By_Location.DYN (81.0 KB)

1 Like