Allocations MVectors

Why does this:

m! = factorial(3)
@btime MVector{$m!, Float64}(undef);
576.677 ns (10 allocations: 512 bytes)

allocate ten times as much as this:

@btime MVector{6, Float64}(undef);
4.148 ns (1 allocation: 64 bytes)

I would like to have the dimension of the MVector as a variable in my function. Yet I will only create these MVectors once.

1 Like

Probably because the $m! acts to make it so the size of the MVector is unknown at compile time.

But the problem remains also if I set

m!::Int = factorial(3)
@btime MVector{$m!, Float64}(undef);

Right because the value of m! is what’s important, not it’s type. If you remove the $ in front of m! you should see the problem go away, as then the compiler can see that m! has constant value 6.

EDIT: actually my suggestion probably won’t work if you’re not doing this in a function.

1 Like

Unfortunately, it still remains. Can you please write the solution you have in mind.

Can you get away with the dimension being a method parameter instead? If the dimension varies a lot at runtime this would only shuttle the same inefficiency outside the method.

Can you please elaborate on this. I am not sure whether I fully grasped the question. m ideally shall be an integer that enters my function “foo(m, …)”. Within that function for a particular method I would like to use

m!::Int = factorial(m)
MVector{m!, Float64}(undef)

Now I see the problem that “m” will only be known at runtime. For my particular problem I can also use “normal” vectors as the speed benefit of MVectors in my particular case is not that big.

I meant something like foo(::Val{m!}) where m! = ... but that function barrier really only helps if you can compute a m! value before doing most of the work in a foo call compiled specifically for said value.

Ah ok, thanks! I think about that.

There’s a section in the Performance Tips about function barriers with a working example, maybe that’ll help as well. It’s not exactly the integer-valued parameter in your MVector case, but it does involve a type parameter computed at runtime. In that example however, the array is still type-unstable where it is instantiated outside the kernel function, rather than being stably instantiated inside the kernel function given a method parameter.

1 Like

Also see this section in the Performance Tips: The dangers of abusing multiple dispatch (aka, more on types with values-as-parameters)

2 Likes