undo off
(
with redraw off
for i = 1 to total do
(
l = copy ny
l.transform = pos[i]
attach olleaves l
)
)
Hi.. This loop is from a kind of scatter thing where "pos" is an array of matrix3 & "ny" is the object I´m scattering ( attaching to "olleaves" )

This works, but is extremely slow.. Any clues on how to speed it up? ( The help file dried out quiet quickly on optimization, and this forum houses braincapacity beyond my imagination )

Your answer is just as fast as your solution ;) Thanks so much!!!
I thought I would be out in some kind of facearray stuff to avoid loading "ny" all the time..

This one is going public so I´m not the only one thankfull ;)

davestewart

05 May 2008, 12:41 PM

Great stuf :)

noontz

05 May 2008, 01:32 PM

Hi Dave...

For what ever crazy reason im afraid your loop doesn´t do the job, when implemented in the rest of my code.. On a test I actually get a slowdown from 8 minutes to 10 minutes, but this could be due to something else, donno ??? ( 7.500 iterations ) Anyway these runtimes are crazy compared to the realtime feedback in for instance the scatter utility, so there must be something hidden under the hood..

davestewart

05 May 2008, 02:10 PM

OK, 7500 sounds like a lot!

Well I don't have much experience with large datasets, but I would suspect that the problem might lie in the fact that as an object's size increases, it becomes increasingly expensive to perform operations on it.

Why don't you try doing, say, 10 iterations of 750 (creating 10 new objects) then a further 10 iterations to attach these 10 new objects together.

It may be that the square root of 7500 might be the best iteration to go for (ie, 86 loops, then, 86 more to attach)

You could store a timestamp after each process in the loop to prove (or disprove) the point

Dave

Bobo

05 May 2008, 02:52 PM

The trouble with attachments is that the Undo buffer gets filled up really fast - each attach operations accumulates the previous version of the mesh, so it grows exponentially.

Thus, if you do not intend to perform an undo after that, you should better add with undo off () around the code. See "How to Make It Faster?" chapter in the MAXScript Reference - the second example in the "Disable Undo system when possible" (at least in the Max 2008 and 2009 version) shows the difference. On my ancient 800MHz system where the original test was performed about 5 years ago, it made the code 20 times faster...

SyncViewS

05 May 2008, 03:07 PM

Hi noontz,
I may have found something that could help you with the speed issue: use the "maxOps.CloneNodes", in place of "copy".
Here two sample scripts and comparison.

-- NOTE: do not use undo off, according to the MAXScript reference it crashes
-- Max if an undo is performed after this operation.
with redraw off
(
for i = 1 to iNumObjects do
(
maxOps.CloneNodes oSample offset:[0,0,0] expandHierarchy:false cloneType:#copy newNodes:&aoTemp
aoTemp[1].transform = am3Transform[i]
aoScatter[i] = aoTemp[1]
)
)

Subtle, but I actually had to generate tens of millions; becomes a little less subtle. This is on a slower machine, though :)

-- --------------------------------------------------

Here's another favorite.. UI updates. UI updates are slow.
ProgressBars are a very popular method of showing, well, progress. But updating them all the time is slow. Update them only periodically. For example, only if the update would actually show in the progress bar (depending on its width).

Another one, no code for obvious reasons.. f you have an intense loop with a lot of if-tests to validate a value; for example to prevent OOB accesses or so, consider try/catch. Typically try/catch is slower than if-tests, but with enough if-tests, try/catch may just win. Pretty rare, and probably not recommended practice; but if you're going for speed...

-- --------------------------------------------------

An old favorite... always name the objects you create, as max will otherwise waste time trying to find a unique name for the new object (obviously only do this if you have no fear of creating non-unique names). This assumes cloneNodes cannot be used for whatever reason.

Large meshes can get exponentially slower for certain operations. In a script I wrote to export grids from TIN's using RayMeshGridIntersect, I resorted to splitting up the TIN before doing intersections, which greatly reduced the running time of the script.

When it comes to copying mesh-data, I immediately thought that perhaps it would be faster to use a Trimesh instead of a node, but I'm not sure how that would affect your transforms.

Someone mentioned if-sentences; sometimes it is not convenient to structure your code optimally to minimize if-sentence overhead (like duplicating a lot of similar, large loops for different outcomes). On one such occation I used a function variable with great success. Prepare a number of predefined functions for each outcome and then assign the appropriate one to a variable before you start the loop. Then your loop can handle different cases without any (unnecessary) if-sentences.

noontz

05 May 2008, 01:45 PM

Hi everybody..

Thanks so much for following up! I´m monster busy & won´t have time to implement & test before next week as mentioned to Dave in a PM ( anyone interested in optimization should check his blog ), but please let the ideas come rolling.. I´m all ears ( but no brains ATM )

davestewart

05 May 2008, 01:59 PM

If you haven't already seen from the link above, I've updated my TimeStamper struct. It provides a set of useful methods and properties for all things timing, including:

basic start / stop / and then print / alert the result
multiple starts then print / alert the average / total
differences bewteen different TimeStampers (for comparison tasks)
full reporting on all timed tasks, including a breakdown on which iterations were fastest, that can be used straight-off-the-bat in Excel (see graph below)
You can run multiple timers (each stored in a variable), and the base messaging functions print stuff in English, i.e. "Processing 'Task Name' took 7.81 seconds"

Here's the dump of the tests run above, copied to Excel and a graph made on the columns:

http://www.keyframesandcode.com/resources/maxscript/For%20Scripters/Time%20Stamper/img/time-stamper-graph.gif
The project home page is here: http://www.keyframesandcode.com/code/development/maxscript/time-stamper/

Ideas and suggestions welcome.

Cheers,
Dave

reForm

01 January 2009, 03:08 PM

Thought I'd bump this thread just to thank the previous poster(Dave) for the meshop-attach optimisation.... from 215seconds down to 1second.... quality! :)

davestewart

01 January 2009, 09:47 AM

Aw, thanks Patrick, that's very nice of you!

Vsai

03 March 2009, 07:41 PM

You rock! I wish i'd seen this earlier today before crashing max a hundred times trying to speed it up! ;)

CGTalk Moderation

03 March 2009, 07:41 PM

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.

Follow Us On:

The CGSociety

The CGSociety is the most respected and accessible global organization for creative digital artists. The CGS supports artists at every level by offering a range of services to connect, inform, educate and promote digital artists worldwide. More about us on TheArtSociety.com