How to create a StaticArray with a variable size?

I’m trying to do something like:

x = 2
y = 3
sa = StaticArray(Int32, x*y).new { |i| i * 2 }
p! sa

But, it complains with:

syntax error in eval:3
Error: unexpected token: "x"

(See: Carcin)

This looks kinda like Is there a way to combine special argument types that denote size through macros? .

1 Like

I can do something like:

x = 2
y = 3
sa = Array.new(x*y) { |i| 0.1 * (i % y) + (i // y) }
p! sa # [0.0, 0.1, 0.2, 1.0, 1.1, 1.2]

See: Carcin

But, I’m wanting to get the performance of a StaticArray. :frowning:

You can’t. This would have been a compiler extension in C.

However if sa is the last member of a class or struct (i.e. a VLA), then you could define it as a one-element StaticArray, manually create a larger buffer, then reinterpret that buffer through a pointer cast. (In fact this is what String does.)

1 Like

@HertzDevil , Thanks. Do you think that would be any more performant than just using Arrays in the first place? (I’d have to look up how to “reinterpret that buffer through a pointer cast”.)

An Array allocates both the array itself and the buffer it points at. Slice might perform slightly better but you shouldn’t be using it over Array as a micro-optimization. Your program’s memory access patterns might matter more than the differences between stack and heap allocations.

1 Like

Allocating the whole array at once helps a bit. See the docs for how to do that.

2 Likes

If you know the maximum value for x*y (which you should, if you want to place it on the stack) and it’s acceptable to occupy that much space even for smaller sizes, you could just always allocate a static array with the maximum size, and then scale down according to the runtime size value.

3 Likes

Max size for the static array won’t be known, but I’ll keep that approach in mind. Thanks @straight-shoota .

How do you resize a static array?

You don’t. It is allocated either on the stack or in an object or struct instance, with a size known during compile time. That gives you certain upsides, at the cost that it cannot be resized. You can do weird shit with pointer casts as hertzdevil mentioned, but it wouldn’t help a lot.

What are you actually trying to do? What led you into this line of inquiry?

I’m wanting to create a multi dimensional array class.

The best thing would be for you to share what API you have in mind. Then we can think what types can implement that API with efficiency in mind.

1 Like

You can’t resize the actual static array, but you can create a slice pointing to it and resize that accordingly.

See also: How to create a (non-static) Nested Array with a variable nested size?

I had a similar problem, but all possible sizes for the array were known, so I ended up with a massive case allocating the array for each possible size required.