I am working on a rather large project that will be calculation intensive. For all purposes you can imagine a geometric ray tracer that considers multiple parameters as an input and performs calculations based on the criteria and geometric relations between emitters and receivers.
I am currently working on a draft version with standard GH components and C# when needed. My final implementation would be a complete GH component created in C# but I have a pressing doubt regarding performance. Current refreshing times are around half a second for basic inputs and a few hundred to a few thousand rays and I am worried these will increase exponentially with more rays and criteria. So my question is related to performance differences between a GH definition and the equivalent GH component built from scratch in C#, what can I expect? What are my best strategies for processing economy?
C# and code is generally much faster, but that also depends on how you code. GH tends to build up a lot of excess geometry to which you then run tests on for filtering (culling, listing). Code runs in loops so it tends to avoid all that excess geometry creation by nature.
Should increase linearly with number of rays I’d say, although increased ray splitting depth may be exponential.
What method are you using for geometry/ray intersections? This is typically the slowest part of a ray-tracer and where optimisations make the most sense.
It can be significant, especially if it involves a lot of data transport. Every time data flows from one component to another, a whole bunch of checking and potentially converting goes on. This overhead can be eliminated entirely in a pure C# program. You may also be able to get rid of a lot of data duplication. Grasshopper always copies data before it modifies it, so if you know that you won’t use an array of points any more you can get away with modifying it directly.
Finally, it’ll be a lot easier to multi-thread some code you own instead of a bunch of Grasshopper components.
Thank you both for the reassurance.
Indeed, this is where I get over 90% of the processing time.
My procedure is :
1 - Divide target surface(s) with equal spacing (spacing is controllable)
2 - Connect points to emitter (rays)
3 - Intersect all rays with isointensity envelope surface (Intersection.CurveBrep)
4 - Check if ray produces intersection (ray.ClosestPoint) and add to list valid rays
5 - Calculation ensues based on distances, angles and intersection point parameter
This was my best guess to strictly use valid/useful rays and discard everything else geometrically before the calculation phase begins. For now only direct rays are of interest, no bouncing necessary.
I’m looking into multi-threading operations possible to implement.
I’ll also be trying with GH geometry instead.
Thanks for your help.
This is slow. You’ll probably get much faster results if you use Mesh Ray intersections.
I did get much faster results with Mesh-Ray intersection. I’m also getting around 25% faster processing time with a custom C# component comparing to the equivalent GH definition. This is already a good improvement.
Now I’m looking into multi-threading some operations, especially the ones inside loops. The bulk of the processing is precisely the computation of intersections between geometries.
What would be my best approach to the multi-threading of
foreach loops, the “dos” and “don’ts”?