When a StaticArray defined as an instance variable is referenced by "@" from multiple different methods, does it get copied?

StaticArray is often faster than Array. However, they cannot be referenced beyond the method.

def x(ar)
  ar[1] += 1

a = StaticArray[0,0,0]


p a # StaticArray[0, 0, 0]

This problem can be solved by using instance variables.

class A
  getter a : StaticArray(Int32, 3)

  def initialize
    @a = StaticArray[0,0,0]
  def x
    @a[1] += 1

a = A.new
p a.a # StaticArray[0, 0, 0]

p a.a # StaticArray[0, 1, 0]

Is “@a” cloned each time it is used in a new and different method?
Or is there no need to worry about such things?

I’m not sure I understand the question… @a always refers to the same ivar and is always accessed in the same way.

My understanding is that struct types stored in ivars are copied when you access them via methods, like the ones defined by getter, but if you access them with the @, I believe that accesses it directly and there’s no copy.

They can be referenced outside the method, but mutating them gets tricky. They need to be mutable because they’re used as buffers that avoid heap allocations, but if you need them to be mutable in multiple places in your app simultaneously, you’re better off using an Array.

The performance of StaticArray comes from the fact that it doesn’t involve any heap allocations, but your workaround wraps it in a class instance, which adds a heap allocation back in. It does avoid one heap allocation (Array contains 2) because it doesn’t have to allocate a buffer, but making it work like a fully functional (though not expandable) array would take significant effort.


edited because I hit post too soon :upside_down_face:

1 Like

I could not explain my question well. But I am glad @jgaskins understood my question and explained it well. What you said makes sense to me. StaticArray is faster to copy than Arrays, but it can be slower if you mutate many times in different parts of the app. This agrees with my observation. Thanks for explaining.

1 Like