Search code examples
performance3dsmaxmaxscript

Pass by value / reference performance comparison in Maxscript?


How does it affect efficiency in Maxscript?. Maxscript is a slow one, but i wonder how much does it affect?

I tried this script, it took a lot of time to execute the operations in the array, but later on the call to functions were fast returning 0 to the time diference (i tried a very high item count in the array).

fn testear lista =
(
    a = 1 + 2
)

fn testear2 &lista =
(
    a = 1 + 2
)

fn inicio = 
(
    lista = #()

    for i = 1 to 1000000 do 
    (
        append lista "hola"
    )

    strTime = timeStamp()
    testear(lista)
    endTime = timeStamp()
    format "\ninicio % final % -> diferencia %\n" strTime endTime (endTime - strTime)

    strTime = timeStamp()
    testear2(&lista)
    endTime = timeStamp()
    format "\ninicio % final % -> diferencia %\n" strTime endTime (endTime - strTime)

    for i = 1 to lista.count do
        deleteItem lista 1

)

inicio()

Solution

  • If you pass an array to a function it automatically gets passed as reference. Those two functions are doing the same thing. Try this:

    fn test1 arr = (
      arr[1] = "test1"
    )
    fn test2 &arr = (
      arr[1] = "test2"
    )
    fn init = (
      testArray = #(1,2,3,4,5,6,7,8,9,0)
      format "Test #1: %\n" testArray
      test1 testArray
      format "Test #2: %\n" testArray
      test2 &testArray
      format "Test #3: %\n" testArray
    
    )
    init()
    

    Notice 'testArray' gets changed by the test functions and the change is reflected outside the test functions' scope.

    However, array operations can take up a lot of time. When you append to an array, like you do in your code, it basically creates a copy of your array every time you add a new item.

    A faster method would be to create an array the size you need initially:

    lista=#()
    lista[1000000] = ""
    for i = 1 to 1000000 do 
    (
      lista[i] = "hola"
    )
    

    Deleting every item in the array took the longest, but I don't think you need to do that. Maxscript does a lot of the garbage collection for you so when your script terminates it should free up that memory. Maybe you could try this:

    for i = 1 to lista.count do
    (
      lista[i] = undefined
    )
    lista = undefined
    

    But again, I don't think it's necessary. You can call the built-in garbage collection function:

    gc()
    

    Hope that answers your question.