Itoo Software Forum

Author Topic: Nonlinear Maxscript Interface performance  (Read 1611 times)

Straightface Studios

  • Newbie
  • *
  • Posts: 15
    • Straightface Studios
Nonlinear Maxscript Interface performance
« on: March 16, 2017, 06:57:39 PM »
So I'm trying to find the source of a bottleneck but can't seem to figure it out.

If I create 1000 trees through maxscript it takes : 4.773s  (4.7ms per tree)
If I create 10000 trees through maxscript it takes : 94.258s (9.5ms per tree)
If I create 10000 trees through maxscript (with update per loop) it takes : 156.157s (15.6ms per tree)
If I create 620000 trees through maxscript it takes : > 64,000.000s  (>100ms per tree Cancelled)

So I thought I would get clever and run a trees.update();trees.update_ui() every 1,000 added trees as that seemed to be the most efficient batch size.  But that ran even slower. 

I tried running trees.update() and/or trees.update_ui() on every loop like the instance objects script in your examples but that ran the very slowest of all.   


forest = Forest_Pro name:"ForestProObject" mode:1 isSelected:false
obj = box()
forest.mode = 1
forest.cobjlist[1] = obj
forest.geomlist[1] = 2

forest.trees.update()
forest.trees.update_ui()

print "starting"
disablesceneredraw()
t = timestamp()

for j = 1 to 10 do (
   for i = 1 to 1000 do
   (
      forest.trees.create [i,i,i] 1 1 1
      --forest.trees.update()
   )
   --forest.trees.update()
   --forest.trees.update_ui()
)
forest.trees.update()
forest.trees.update_ui()
print (timestamp()-t)
enablesceneredraw()


Michal Karmazín

  • iToo Software
  • Hero Member
  • *****
  • Posts: 1547
Re: Nonlinear Maxscript Interface performance
« Reply #1 on: March 17, 2017, 03:19:24 PM »
Hi,

This behaviour is related to necessity of new arrays creation and copying existing elements as it grows. It's typical for dynamic arrays - thought it's theoretically  possible to add a functionality to reserve the space upon the amount of items in future releases, it might bring unwanted effects and it needs to be treated very carefully. Thanks for your comprehension.

Best regadrs,

Straightface Studios

  • Newbie
  • *
  • Posts: 15
    • Straightface Studios
Re: Nonlinear Maxscript Interface performance
« Reply #2 on: March 18, 2017, 02:04:06 AM »
I guess it's a feature request then. :D Instead of dynamically growing the array by .add(item) do a join(#(<treestructs>,<treestructs>)) and let me push in a few thousand trees at a time.  Somewhere in your core you have this functionality for the Create From Triangle Center feature.  And that's nearly instantaneous. 

iToo

  • Administrator
  • Hero Member
  • *****
  • Posts: 3320
    • iToo Software
Re: Nonlinear Maxscript Interface performance
« Reply #3 on: December 21, 2017, 10:28:26 AM »
Hi, in Forest 6 we have replaced the standard array functions by our own custom system, which is much more efficient handling huge arrays.

I've done some tests with your script, and these are the results:

10k items: 6.992 sec.
100k items: 119.412 sec.

As you can see, now is much more manageable.
Checking the code, i cannot find more ways to optimize it. I guess now the bottleneck is Maxscript and the internal Max workflow.

Hopefully the first beta of FP6 will be available very soon. The code is completed, and we are now reorganizing and adding new libraries.

Carlos Quintero
iToo Software

iToo

  • Administrator
  • Hero Member
  • *****
  • Posts: 3320
    • iToo Software
Re: Nonlinear Maxscript Interface performance
« Reply #4 on: December 21, 2017, 10:31:28 AM »
I've attached the modified script to this post.
I had to do some changes to make it work with FP6. I also added "disableRefMsgs() / enableRefMsgs()", which may improve performance a bit.
Carlos Quintero
iToo Software

amitgedia

  • Jr. Member
  • **
  • Posts: 74
Re: Nonlinear Maxscript Interface performance
« Reply #5 on: December 22, 2017, 09:35:07 AM »
Hi,
Is this script only useful for FP6 or can it be used with existing version as well, if so where to place it or replace it...
Thanks

iToo

  • Administrator
  • Hero Member
  • *****
  • Posts: 3320
    • iToo Software
Re: Nonlinear Maxscript Interface performance
« Reply #6 on: December 22, 2017, 10:07:23 AM »
Hi, with the modifications i did, the script is valid both for FP5 and FP6.
The script is a custom tool written by the user, to generate a FP object with items automatically. It doesn't come with the standard Forest installation.

For your information, in FP6 it's possible to create an object without any item in the Geometry list. Therefore, the previous script was failing because initially the list doesn't contain any item.
I just added one value to all parameters of the list, so it's initialized correctly.
Carlos Quintero
iToo Software

Dave_Wortley

  • Newbie
  • *
  • Posts: 1
Re: Nonlinear Maxscript Interface performance
« Reply #7 on: January 24, 2018, 02:17:52 AM »
Thought this was worth sharing.

For 100,000 items
Carlos's code
Elapsed Time: 6258.97 sec.

With the Forest system disabled whilst adding trees
Elapsed Time: 608.561 sec.

With undo off added as well.
Elapsed Time: 431.485 sec.


Code: [Select]
forest = Forest_Pro name:"ForestProObject" mode:1 isSelected:false
obj = box()

/* point-cloud mode */
forest.vmesh = 3

/* geometry creation */
forest.cobjlist[1] = obj
forest.matlist[1] = undefined
forest.namelist[1] = obj.name
forest.coloridlist[1] = [1,0,0]
forest.geomlist[1] = 2
forest.tempidlist[1] = 1
forest.tempnamelist[1] = "One Plane"
forest.widthlist[1] = 2
forest.heightlist[1] = 3
forest.scalelist[1] = 100
forest.zoffsetlist[1] = 0
forest.centerlist[1] = 50
forest.radiuslist[1] = 100
forest.usemeshdimlist[1] = true
forest.problist[1] = 100
forest.conamelist[1] = obj.name
forest.old_problist[1] = 100

forest.trees.update()
forest.trees.update_ui()
forest.disabled = true --the magic line which speeds things up 10x.

/* create items along a grid */
print "starting"
with undo off with redraw off
(
disableRefMsgs()
t = timestamp()

sx = obj.width
dx = obj.width * 1.1
for x = 1 to 100 do (
   for y = 1 to 1000 do
   (
  forest.trees.create [x*dx , y*dx, 0] sx sx 1
   )
)
forest.disabled = false
forest.trees.update()
forest.trees.update_ui()
format "Elapsed Time: % sec.\n" ((timestamp() - t) / 1000.0)
enableRefMsgs()
)