While experimenting with some performance bottlenecks, I found that
h1(n) = ntuple(i -> collect(0:1/n:1), 3)
@code_warntype h1(5)
show type instability (it cannot infer 3 as the length of the tuple), while
f(n) = ntuple(i -> n, 3)
g(n) = collect(0:1/n:1)
h2(n) = f(g(n))
@code_warntype h2(5)
seems to be fine.
I feel like this is non-expected behaviour and if possible I’d like h1
to be type stable without the need to split it up like that. Is this a known issue or am I just doing things the wrong way?
On 0.6 both versions are type-unstable; presumably on 0.7 the second version is simple enough to benefit from the new constant-propagation optimization.
Anyway, you can pass Val{3}()
if you want to force the length 3
to be a compile-time constant.
PS. Your h1
and h2
are inequivalent in another way: h1
has a different collected
array in each tuple element, whereas h2
has a tuple of three references to the same array.
2 Likes
Sorry for not mentioning, I’m on 0.7 master right now.
Thanks! I didn’t even know you could pass Val{n}()
to ntuple
, that is nice.
There might be other calls to Base
-functions in my code, where I can pass Val{n}()
s to enforce type stability.
Yes, h1
and h2
are indeed different in that sense, I didn’t notice when I put together the example.
Note that you can write Val(3) instead. EDIT: On Julia 0.7
3 Likes