# Why does indexing into CartesianIndices lead to excessive runtime dispatch?

**URL:** <https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438>\
**Category:** Performance\
**Created:** [February 20, 2024, 7:22am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438 "2024-02-20T07:22:23Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [February 20, 2024, 7:22am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/1 "2024-02-20T07:22:23Z")

</div>

This just looks so weird to me. The code is really simply:

```julia
function neighbors(d::Int)
    n_ = CartesianIndices((fill(-1:1, d)...,))
    n = n_[begin:end//2] #This line runtime errors
end

```

```julia
using JET

@report_opt neighbors(2)

═════ 106 possible errors found ═════
┌ neighbors(d::Int64) @ Main c:\git\SPHExample\example\TempRepoCLL.jl:39
│┌ firstindex(a::CartesianIndices{N, R} where {N, R<:Tuple{Vararg{UnitRange{Int64}, N}}}) @ Base ./abstractarray.jl:446
││┌ eachindex(::IndexLinear, A::CartesianIndices{N, R} where {N, R<:Tuple{Vararg{UnitRange{Int64}, N}}}) @ Base ./abstractarray.jl:385
│││┌ oneto(r::Any) @ Base ./range.jl:469
││││┌ Base.OneTo(r::AbstractRange{T}) where T<:Integer @ Base ./range.jl:468
│││││┌ Base.OneTo{T}(r::Base.OneTo) where T<:Integer @ Base ./range.jl:1301
││││││┌ (::Type{Base.OneTo{T}} where T<:Integer)(stop::Integer) @ Base ./range.jl:453
│││││││┌ (::Base.var"#throwbool#81")(r::Integer) @ Base ./range.jl:452
││││││││┌ string(::String, ::Integer, ::String) @ Base ./strings/io.jl:189
│││││││││┌ print_to_string(::String, ::Integer, ::String) @ Base ./strings/io.jl:148
││││││││││┌ print(io::IOBuffer, n::Unsigned) @ Base ./show.jl:1197
│││││││││││┌ string(n::Unsigned) @ Base ./intfuncs.jl:833
││││││││││││┌ string(n::Unsigned; base::Int64, pad::Int64) @ Base ./intfuncs.jl:837
│││││││││││││┌ bin(x::Unsigned, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:715
││││││││││││││┌ setindex!(::Vector{UInt8}, ::UInt8, ::Union{Integer, CartesianIndex}) @ Base ./multidimensional.jl:698
│││││││││││││││┌ to_indices(A::Vector{UInt8}, I::Tuple{Integer}) @ Base ./indices.jl:350
││││││││││││││││┌ to_indices(A::Vector{UInt8}, inds::Tuple{}, I::Tuple{Integer}) @ Base ./indices.jl:354
│││││││││││││││││┌ _to_indices1(A::Vector{UInt8}, inds::Tuple{}, I1::Integer) @ Base ./indices.jl:359
││││││││││││││││││┌ to_index(A::Vector{UInt8}, i::Integer) @ Base ./indices.jl:277
│││││││││││││││││││┌ to_index(i::Bool) @ Base ./indices.jl:293
││││││││││││││││││││┌ string(::String, ::Bool, ::String) @ Base ./strings/io.jl:189
│││││││││││││││││││││┌ print_to_string(::String, ::Vararg{Any}) @ Base ./strings/io.jl:143
││││││││││││││││││││││ runtime dispatch detected: Base._str_sizehint(%15::Any)::Int64
│││││││││││││││││││││└────────────────────
│││││││││││││││││││││┌ print_to_string(::String, ::Vararg{Any}) @ Base ./strings/io.jl:148
││││││││││││││││││││││ runtime dispatch detected: print(%40::IOBuffer, %53::Any)::Any
│││││││││││││││││││││└────────────────────
││││││││││││││││││││┌ string(::String, ::Bool, ::String) @ Base ./strings/io.jl:189
│││││││││││││││││││││ failed to optimize due to recursion: string(::String, ::Bool, ::String)
││││││││││││││││││││└────────────────────
│││││││││││││││││││┌ to_index(i::Bool) @ Base ./indices.jl:293
││││││││││││││││││││ failed to optimize due to recursion: Base.to_index(::Bool)
│││││││││││││││││││└────────────────────
││││││││││││││││┌ to_indices(A::Vector{UInt8}, inds::Tuple{}, I::Tuple{Integer}) @ Base ./indices.jl:354
│││││││││││││││││ runtime dispatch detected: Base._to_indices1(A::Vector{UInt8}, inds::Tuple{}, %1::Integer)::Tuple{Int64}
││││││││││││││││└────────────────────
│││││││││││││││┌ to_indices(A::Vector{UInt8}, I::Tuple{Union{Integer, CartesianIndex}}) @ Base ./multidimensional.jl:859
││││││││││││││││┌ to_indices(A::Vector{UInt8}, inds::Tuple{}, I::Tuple{Union{Integer, CartesianIndex}}) @ Base ./indices.jl:355
│││││││││││││││││┌ _cutdim(inds::Tuple{}, I1::CartesianIndex) @ Base ./multidimensional.jl:863
││││││││││││││││││┌ split(t::Tuple{}, V::Val) @ Base.IteratorsMD ./multidimensional.jl:487
│││││││││││││││││││ runtime dispatch detected: Base.IteratorsMD.ntuple(Returns{Bool}(true), V::Val)::Any
││││││││││││││││││└────────────────────
││││││││││││││││┌ to_indices(A::Vector{UInt8}, inds::Tuple{}, I::Tuple{Union{Integer, CartesianIndex}}) @ Base ./indices.jl:354
│││││││││││││││││ runtime dispatch detected: Base._to_indices1(A::Vector{UInt8}, inds::Tuple{}, %1::Union{Integer, CartesianIndex})::Any
││││││││││││││││└────────────────────
││││││││││││││││┌ to_indices(A::Vector{UInt8}, inds::Tuple{}, I::Tuple{Union{Integer, CartesianIndex}}) @ Base ./indices.jl:355
│││││││││││││││││ runtime dispatch detected: Base._cutdim(inds::Tuple{}, %3::Union{Integer, CartesianIndex})::Tuple{}
││││││││││││││││└────────────────────
││││││││││││││┌ setindex!(A::Vector{UInt8}, v::UInt8, I::Any) @ Base ./abstractarray.jl:1393
│││││││││││││││ runtime dispatch detected: to_indices(A::Vector{UInt8}, I::Tuple{Any})::Any
││││││││││││││└────────────────────
│││││││││││││┌ bin(x::Unsigned, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:719
││││││││││││││┌ >>(x::Unsigned, c::UInt8) @ Base ./operators.jl:701
│││││││││││││││ runtime dispatch detected: (x::Unsigned >> 4)::Any
││││││││││││││└────────────────────
│││││││││││││┌ bin(x::Unsigned, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:724
││││││││││││││┌ >>(x::Integer, c::UInt8) @ Base ./operators.jl:701
│││││││││││││││ runtime dispatch detected: (x::Integer >> 1)::Any
││││││││││││││└────────────────────
││││││││││││┌ string(n::Unsigned; base::Int64, pad::Int64) @ Base ./intfuncs.jl:840
│││││││││││││┌ oct(x::Unsigned, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:738
││││││││││││││┌ >>(x::Unsigned, c::UInt8) @ Base ./operators.jl:701
│││││││││││││││ runtime dispatch detected: (x::Unsigned >> 3)::Any
││││││││││││││└────────────────────
││││││││││││││┌ >>(x::Integer, c::UInt8) @ Base ./operators.jl:701
│││││││││││││││ runtime dispatch detected: (x::Integer >> 3)::Any
││││││││││││││└────────────────────
││││││││││││┌ string(n::Unsigned; base::Int64, pad::Int64) @ Base ./intfuncs.jl:843
│││││││││││││┌ dec(x::Unsigned, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:749
││││││││││││││┌ kwcall(::@NamedTuple{pad::Int64}, ::typeof(ndigits), x::Unsigned) @ Base ./intfuncs.jl:700
│││││││││││││││┌ ndigits(x::Unsigned; base::Int64, pad::Int64) @ Base ./intfuncs.jl:700
││││││││││││││││┌ ndigits0z(x::Unsigned, b::Int64) @ Base ./intfuncs.jl:659
│││││││││││││││││┌ ndigits0znb(x::Unsigned, b::Int64) @ Base ./intfuncs.jl:578
││││││││││││││││││┌ !=(x::Unsigned, y::Int64) @ Base ./operators.jl:276
│││││││││││││││││││┌ ==(x::Unsigned, y::Int64) @ Base ./promotion.jl:461
││││││││││││││││││││┌ promote(x::Unsigned, y::Int64) @ Base ./promotion.jl:393
│││││││││││││││││││││┌ _promote(x::Unsigned, y::Int64) @ Base ./promotion.jl:369
││││││││││││││││││││││┌ promote_type(::Type{T} where T<:Unsigned, ::Type{Int64}) @ Base ./promotion.jl:313
│││││││││││││││││││││││┌ promote_result(::Type{T} where T<:Unsigned, ::Type{Int64}, ::Type{T}, ::Type{Int64}) where T @ Base ./promotion.jl:333
││││││││││││││││││││││││┌ promote_type(::Type, ::Type{Int64}) @ Base ./promotion.jl:313
│││││││││││││││││││││││││┌ promote_result(::Type{T}, ::Type{Int64}, ::Type{Union{}}, ::Type{Union{}}) where T @ Base ./promotion.jl:336
││││││││││││││││││││││││││┌ typejoin(a::Type, b::Type{Int64}) @ Base ./promotion.jl:34
│││││││││││││││││││││││││││┌ typejoin(a::Any, b::Type{Int64}) @ Base ./promotion.jl:38
││││││││││││││││││││││││││││┌ typejoin(a::Any, b::Any) @ Base ./promotion.jl:127
│││││││││││││││││││││││││││││ runtime dispatch detected: Base.UnionAll(%403::Any, %405::Any)::Any
││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││┌ typejoin(a::Any, b::Type{Int64}) @ Base ./promotion.jl:127
││││││││││││││││││││││││││││ runtime dispatch detected: Base.UnionAll(%381::Any, %383::Any)::Any
│││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││┌ typejoin(a::Type, b::Type{Int64}) @ Base ./promotion.jl:127
│││││││││││││││││││││││││││ runtime dispatch detected: Base.UnionAll(%376::Any, %378::Any)::Any
││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││┌ promote_result(::Type, ::Type{Int64}, ::Type{T}, ::Type{Int64}) where T @ Base ./promotion.jl:333
│││││││││││││││││││││││││ runtime dispatch detected: promote_type(%1::Type, ::Int64)::Any
││││││││││││││││││││││││└────────────────────
││││││││││││││││││││┌ promote(x::Unsigned, y::Int64) @ Base ./promotion.jl:394
│││││││││││││││││││││┌ not_sametype(x::T, y::T) where T<:Tuple{Unsigned, Int64} @ Base ./promotion.jl:411
││││││││││││││││││││││┌ sametype_error(input::Tuple{Unsigned, Int64}) @ Base ./promotion.jl:417
│││││││││││││││││││││││┌ map(f::Base.var"#46#47", t::Tuple{Unsigned, Int64}) @ Base ./tuple.jl:292
││││││││││││││││││││││││┌ (::Base.var"#46#47")(x::Unsigned) @ Base ./promotion.jl:418
│││││││││││││││││││││││││┌ string(xs::Type{<:Unsigned}) @ Base ./strings/io.jl:189
││││││││││││││││││││││││││┌ print_to_string(xs::Type) @ Base ./strings/io.jl:148
│││││││││││││││││││││││││││┌ print(io::IOBuffer, x::Type) @ Base ./strings/io.jl:35
││││││││││││││││││││││││││││┌ show(io::IOBuffer, x::Type) @ Base ./show.jl:953
│││││││││││││││││││││││││││││┌ _show_type(io::IOBuffer, x::Type) @ Base ./show.jl:958
││││││││││││││││││││││││││││││┌ show_typealias(io::IOBuffer, x::Type) @ Base ./show.jl:793
│││││││││││││││││││││││││││││││┌ make_typealias(x::Type) @ Base ./show.jl:603
││││││││││││││││││││││││││││││││┌ modulesof!(s::Set{Module}, x::Type) @ Base ./show.jl:578
│││││││││││││││││││││││││││││││││ runtime dispatch detected: Base.modulesof!(s::Set{Module}, %20::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ modulesof!(s::Set{Module}, x::Type) @ Base ./show.jl:579
│││││││││││││││││││││││││││││││││ runtime dispatch detected: Base.modulesof!(s::Set{Module}, %35::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ modulesof!(s::Set{Module}, x::TypeVar) @ Base ./show.jl:572
│││││││││││││││││││││││││││││││││ runtime dispatch detected: Base.modulesof!(s::Set{Module}, %1::Any)::Set{Module}
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_typealias(io::IOBuffer, x::Type) @ Base ./show.jl:796
│││││││││││││││││││││││││││││││┌ show_typealias(io::IOBuffer, name::GlobalRef, x::Type, env::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:743
││││││││││││││││││││││││││││││││┌ show_typeparams(io::IOContext{IOBuffer}, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:707
│││││││││││││││││││││││││││││││││┌ show(io::IOContext{IOBuffer}, tv::TypeVar) @ Base ./show.jl:2737
││││││││││││││││││││││││││││││││││┌ (::Base.var"#show_bound#566")(io::IOContext{IOBuffer}, b::Any) @ Base ./show.jl:2729
│││││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOContext{IOBuffer}, b::Any)::Any
││││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ show_typeparams(io::IOContext{IOBuffer}, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:702
│││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOContext{IOBuffer}, %243::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ show_typeparams(io::IOContext{IOBuffer}, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:705
│││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOContext{IOBuffer}, %294::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ show_typeparams(io::IOContext{IOBuffer}, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:710
│││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOContext{IOBuffer}, %192::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││┌ _show_type(io::IOBuffer, x::Type) @ Base ./show.jl:961
││││││││││││││││││││││││││││││┌ show_datatype(io::IOBuffer, x::DataType) @ Base ./show.jl:1077
│││││││││││││││││││││││││││││││┌ show_datatype(io::IOBuffer, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1080
││││││││││││││││││││││││││││││││┌ maybe_kws_nt(x::DataType) @ Base ./show.jl:1068
│││││││││││││││││││││││││││││││││ runtime dispatch detected: eltype(%79::DataType)::Any
││││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││││┌ show_datatype(io::IOBuffer, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1130
││││││││││││││││││││││││││││││││┌ show_typeparams(io::IOBuffer, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:707
│││││││││││││││││││││││││││││││││┌ show(io::IOBuffer, tv::TypeVar) @ Base ./show.jl:2737
││││││││││││││││││││││││││││││││││┌ (::Base.var"#show_bound#566")(io::IOBuffer, b::Any) @ Base ./show.jl:2729
│││││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOBuffer, b::Any)::Any
││││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ show_typeparams(io::IOBuffer, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:702
│││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOBuffer, %241::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ show_typeparams(io::IOBuffer, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:705
│││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOBuffer, %291::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ show_typeparams(io::IOBuffer, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar}) @ Base ./show.jl:710
│││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOBuffer, %191::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││││┌ show_datatype(io::IOBuffer, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1096
││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOBuffer, %94::Any)::Any
│││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││││┌ show_datatype(io::IOBuffer, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1102
││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOBuffer, %141::Any)::Any
│││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││││┌ show_datatype(io::IOBuffer, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1106
││││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOBuffer, %162::Any)::Any
│││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││││┌ show_datatype(io::IOBuffer, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1116
││││││││││││││││││││││││││││││││ runtime dispatch detected: Base.show_at_namedtuple(io::IOBuffer, %219::Tuple, %220::DataType)::Any
│││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││┌ _show_type(io::IOBuffer, x::Type) @ Base ./show.jl:964
││││││││││││││││││││││││││││││┌ show_unionaliases(io::IOBuffer, x::Union) @ Base ./show.jl:884
│││││││││││││││││││││││││││││││┌ make_typealiases(x::Union) @ Base ./show.jl:805
││││││││││││││││││││││││││││││││┌ modulesof!(s::Set{Module}, x::Union) @ Base ./show.jl:578
│││││││││││││││││││││││││││││││││ runtime dispatch detected: Base.modulesof!(s::Set{Module}, %3::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││││┌ modulesof!(s::Set{Module}, x::Union) @ Base ./show.jl:579
│││││││││││││││││││││││││││││││││ runtime dispatch detected: Base.modulesof!(s::Set{Module}, %17::Any)::Any
││││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_unionaliases(io::IOBuffer, x::Union) @ Base ./show.jl:897
│││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOBuffer, %50::Any)::Any
││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_unionaliases(io::IOBuffer, x::Union) @ Base ./show.jl:903
│││││││││││││││││││││││││││││││ runtime dispatch detected: Base.show_typealias(io::IOBuffer, %133::Any, x::Union, %131::Core.SimpleVector, %132::Vector{TypeVar})::Any
││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_unionaliases(io::IOBuffer, x::Union) @ Base ./show.jl:911
│││││││││││││││││││││││││││││││ runtime dispatch detected: Base.show_typealias(io::IOBuffer, %179::Any, x::Union, %177::Core.SimpleVector, %178::Vector{TypeVar})::Any
││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││┌ _show_type(io::IOBuffer, x::Type) @ Base ./show.jl:968
││││││││││││││││││││││││││││││┌ show_delim_array(io::IOBuffer, itr::Vector{Any}, op::Char, delim::Char, cl::Char, delim_one::Bool) @ Base ./show.jl:1335
│││││││││││││││││││││││││││││││┌ show_delim_array(io::IOBuffer, itr::Vector{Any}, op::Char, delim::Char, cl::Char, delim_one::Bool, i1::Int64, l::Int64) @ Base ./show.jl:1346
││││││││││││││││││││││││││││││││ runtime dispatch detected: show(%4::IOContext{IOBuffer}, %41::Any)::Any
│││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││┌ _show_type(io::IOBuffer, x::Type) @ Base ./show.jl:995
││││││││││││││││││││││││││││││┌ show_datatype(io::IOContext{IOBuffer}, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1129
│││││││││││││││││││││││││││││││┌ show_type_name(io::IOContext{IOBuffer}, tn::Core.TypeName) @ Base ./show.jl:1042
││││││││││││││││││││││││││││││││ runtime dispatch detected: Base.isvisible(%32::Symbol, %89::Module, %83::Any)::Bool
│││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_datatype(io::IOContext{IOBuffer}, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1096
│││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOContext{IOBuffer}, %94::Any)::Any
││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_datatype(io::IOContext{IOBuffer}, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1102
│││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOContext{IOBuffer}, %144::Any)::Any
││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_datatype(io::IOContext{IOBuffer}, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1106
│││││││││││││││││││││││││││││││ runtime dispatch detected: show(io::IOContext{IOBuffer}, %166::Any)::Any
││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_datatype(io::IOContext{IOBuffer}, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1116
│││││││││││││││││││││││││││││││ runtime dispatch detected: Base.show_at_namedtuple(io::IOContext{IOBuffer}, %225::Tuple, %226::DataType)::Any
││││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││││┌ show_datatype(io::IOContext{IOBuffer}, x::DataType, wheres::Vector{TypeVar}) @ Base ./show.jl:1124
│││││││││││││││││││││││││││││││ runtime dispatch detected: Base.show_at_namedtuple(io::IOContext{IOBuffer}, %268::Tuple, %273::DataType)::Any
││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││││││┌ _show_type(io::IOBuffer, x::Type) @ Base ./show.jl:997
││││││││││││││││││││││││││││││ runtime dispatch detected: show(%74::IOContext{IOBuffer}, %75::Any)::Any
│││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││││┌ show(io::IOBuffer, x::Type) @ Base ./show.jl:953
│││││││││││││││││││││││││││││ runtime dispatch detected: Base._show_type(io::IOBuffer, x::Type)::Nothing
││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││┌ (::Base.var"#46#47")(x::Int64) @ Base ./promotion.jl:418
│││││││││││││││││││││││││┌ string(xs::Type{Int64}) @ Base ./strings/io.jl:189
││││││││││││││││││││││││││┌ print_to_string(xs::Type{Int64}) @ Base ./strings/io.jl:148
│││││││││││││││││││││││││││┌ print(io::IOBuffer, x::Type{Int64}) @ Base ./strings/io.jl:35
││││││││││││││││││││││││││││┌ show(io::IOBuffer, x::Type{Int64}) @ Base ./show.jl:953
│││││││││││││││││││││││││││││ runtime dispatch detected: Base._show_type(io::IOBuffer, x::Type{Int64})::Nothing
││││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││┌ promote(x::Unsigned, y::Int64) @ Base ./promotion.jl:393
│││││││││││││││││││││ runtime dispatch detected: Base._promote(x::Unsigned, y::Int64)::Tuple{Any, Any}
││││││││││││││││││││└────────────────────
││││││││││││││││││││┌ promote(x::Unsigned, y::Int64) @ Base ./promotion.jl:394
│││││││││││││││││││││ runtime dispatch detected: Base.not_sametype(%4::Tuple{Unsigned, Int64}, %5::Tuple{Any, Any})::Any
││││││││││││││││││││└────────────────────
│││││││││││││││││┌ ndigits0znb(x::Unsigned, b::Int64) @ Base ./intfuncs.jl:579
││││││││││││││││││┌ fld(x::Unsigned, y::Int64) @ Base ./div.jl:332
│││││││││││││││││││┌ div(x::Unsigned, y::Int64, ::RoundingMode{:Down}) @ Base ./div.jl:283
││││││││││││││││││││┌ divrem(x::Unsigned, y::Int64) @ Base ./int.jl:241
│││││││││││││││││││││┌ divrem(x::Unsigned, y::UInt64) @ Base ./div.jl:179
││││││││││││││││││││││┌ divrem(a::Unsigned, b::UInt64, r::RoundingMode{:ToZero}) @ Base ./div.jl:201
│││││││││││││││││││││││┌ div(a::Unsigned, b::UInt64) @ Base ./div.jl:47
││││││││││││││││││││││││┌ div(x::Unsigned, y::UInt64, r::RoundingMode{:ToZero}) @ Base ./div.jl:343
│││││││││││││││││││││││││┌ promote(x::Unsigned, y::UInt64) @ Base ./promotion.jl:393
││││││││││││││││││││││││││┌ _promote(x::Unsigned, y::UInt64) @ Base ./promotion.jl:370
│││││││││││││││││││││││││││ runtime dispatch detected: convert(%77::Any, x::Unsigned)::Any
││││││││││││││││││││││││││└────────────────────
││││││││││││││││││││││││││┌ _promote(x::Unsigned, y::UInt64) @ Base ./promotion.jl:370
│││││││││││││││││││││││││││ runtime dispatch detected: convert(%77::Any, y::UInt64)::Any
││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││││││││┌ promote(x::Unsigned, y::UInt64) @ Base ./promotion.jl:394
││││││││││││││││││││││││││┌ not_sametype(x::T, y::T) where T<:Tuple{Unsigned, UInt64} @ Base ./promotion.jl:411
│││││││││││││││││││││││││││┌ sametype_error(input::Tuple{Unsigned, UInt64}) @ Base ./promotion.jl:417
││││││││││││││││││││││││││││┌ map(f::Base.var"#46#47", t::Tuple{Unsigned, UInt64}) @ Base ./tuple.jl:292
│││││││││││││││││││││││││││││┌ (::Base.var"#46#47")(x::UInt64) @ Base ./promotion.jl:418
││││││││││││││││││││││││││││││┌ string(xs::Type{UInt64}) @ Base ./strings/io.jl:189
│││││││││││││││││││││││││││││││┌ print_to_string(xs::Type{UInt64}) @ Base ./strings/io.jl:148
││││││││││││││││││││││││││││││││┌ print(io::IOBuffer, x::Type{UInt64}) @ Base ./strings/io.jl:35
│││││││││││││││││││││││││││││││││┌ show(io::IOBuffer, x::Type{UInt64}) @ Base ./show.jl:953
││││││││││││││││││││││││││││││││││ runtime dispatch detected: Base._show_type(io::IOBuffer, x::Type{UInt64})::Nothing
│││││││││││││││││││││││││││││││││└────────────────────
│││││││││││││││││││┌ div(x::Unsigned, y::Int64, ::RoundingMode{:Down}) @ Base ./div.jl:284
││││││││││││││││││││┌ &(a::Bool, b::Integer) @ Base ./int.jl:1065
│││││││││││││││││││││┌ promote_typeof(x::Bool, xs::Integer) @ Base ./promotion.jl:373
││││││││││││││││││││││┌ promote_type(::Type{Bool}, ::Type{<:Integer}) @ Base ./promotion.jl:313
│││││││││││││││││││││││┌ promote_result(::Type{Bool}, ::Type{<:Integer}, ::Type{T}, ::Type{S}) where {T<:Integer, S} @ Base ./promotion.jl:333
││││││││││││││││││││││││ runtime dispatch detected: promote_type(%1::Type{T} where T<:Integer, %2::Type)::Any
│││││││││││││││││││││││└────────────────────
│││││││││││││││││││││┌ promote_typeof(x::Bool, xs::Integer) @ Base ./promotion.jl:373
││││││││││││││││││││││ runtime dispatch detected: promote_type(::Bool, %2::Type{<:Integer})::Any
│││││││││││││││││││││└────────────────────
││││││││││││││││││││┌ &(a::Bool, b::Integer) @ Base ./int.jl:1067
│││││││││││││││││││││┌ not_sametype(x::T, y::T) where T<:Tuple{Bool, Integer} @ Base ./promotion.jl:411
││││││││││││││││││││││┌ sametype_error(input::Tuple{Bool, Integer}) @ Base ./promotion.jl:417
│││││││││││││││││││││││┌ map(f::Base.var"#46#47", t::Tuple{Bool, Integer}) @ Base ./tuple.jl:292
││││││││││││││││││││││││┌ (::Base.var"#46#47")(x::Bool) @ Base ./promotion.jl:418
│││││││││││││││││││││││││┌ string(xs::Type{Bool}) @ Base ./strings/io.jl:189
││││││││││││││││││││││││││┌ print_to_string(xs::Type{Bool}) @ Base ./strings/io.jl:148
│││││││││││││││││││││││││││┌ print(io::IOBuffer, x::Type{Bool}) @ Base ./strings/io.jl:35
││││││││││││││││││││││││││││┌ show(io::IOBuffer, x::Type{Bool}) @ Base ./show.jl:953
│││││││││││││││││││││││││││││ runtime dispatch detected: Base._show_type(io::IOBuffer, x::Type{Bool})::Nothing
││││││││││││││││││││││││││││└────────────────────
││││││││││││││││┌ ndigits0z(x::Unsigned, b::Int64) @ Base ./intfuncs.jl:661
│││││││││││││││││┌ ndigits0zpb(x::Unsigned, b::Int64) @ Base ./intfuncs.jl:611
││││││││││││││││││┌ >(x::Unsigned, y::Int64) @ Base ./operators.jl:378
│││││││││││││││││││┌ <(x::Int64, y::Unsigned) @ Base ./promotion.jl:462
││││││││││││││││││││┌ promote(x::Int64, y::Unsigned) @ Base ./promotion.jl:393
│││││││││││││││││││││┌ _promote(x::Int64, y::Unsigned) @ Base ./promotion.jl:369
││││││││││││││││││││││┌ promote_type(::Type{Int64}, ::Type{S} where S<:Unsigned) @ Base ./promotion.jl:313
│││││││││││││││││││││││┌ promote_result(::Type{Int64}, ::Type{S} where S<:Unsigned, ::Type{Int64}, ::Type{S}) where S @ Base ./promotion.jl:333
││││││││││││││││││││││││┌ promote_result(::Type{Int64}, ::Type, ::Type{Int64}, ::Type{S}) where S @ Base ./promotion.jl:333
│││││││││││││││││││││││││ runtime dispatch detected: promote_type(::Int64, %1::Type)::Any
││││││││││││││││││││││││└────────────────────
││││││││││││││││││││┌ promote(x::Int64, y::Unsigned) @ Base ./promotion.jl:393
│││││││││││││││││││││ runtime dispatch detected: Base._promote(x::Int64, y::Unsigned)::Tuple{Any, Any}
││││││││││││││││││││└────────────────────
││││││││││││││││││││┌ promote(x::Int64, y::Unsigned) @ Base ./promotion.jl:394
│││││││││││││││││││││ runtime dispatch detected: Base.not_sametype(%4::Tuple{Int64, Unsigned}, %5::Tuple{Any, Any})::Any
││││││││││││││││││││└────────────────────
│││││││││││││┌ dec(x::Unsigned, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:753
││││││││││││││┌ divrem(x::Unsigned, y::UInt8) @ Base ./div.jl:179
│││││││││││││││┌ divrem(a::Unsigned, b::UInt8, r::RoundingMode{:ToZero}) @ Base ./div.jl:201
││││││││││││││││┌ div(a::Unsigned, b::UInt8) @ Base ./div.jl:47
│││││││││││││││││┌ div(x::Unsigned, y::UInt8, r::RoundingMode{:ToZero}) @ Base ./div.jl:343
││││││││││││││││││┌ promote(x::Unsigned, y::UInt8) @ Base ./promotion.jl:393
│││││││││││││││││││┌ _promote(x::Unsigned, y::UInt8) @ Base ./promotion.jl:369
││││││││││││││││││││┌ promote_type(::Type{T} where T<:Unsigned, ::Type{UInt8}) @ Base ./promotion.jl:313
│││││││││││││││││││││┌ promote_result(::Type{T} where T<:Unsigned, ::Type{UInt8}, ::Type{T}, ::Type{UInt8}) where T @ Base ./promotion.jl:333
││││││││││││││││││││││┌ promote_result(::Type, ::Type{UInt8}, ::Type{T}, ::Type{UInt8}) where T @ Base ./promotion.jl:333
│││││││││││││││││││││││ runtime dispatch detected: promote_type(%1::Type, ::UInt8)::Any
││││││││││││││││││││││└────────────────────
││││││││││││││││││┌ promote(x::Unsigned, y::UInt8) @ Base ./promotion.jl:394
│││││││││││││││││││┌ not_sametype(x::T, y::T) where T<:Tuple{Unsigned, UInt8} @ Base ./promotion.jl:411
││││││││││││││││││││┌ sametype_error(input::Tuple{Unsigned, UInt8}) @ Base ./promotion.jl:417
│││││││││││││││││││││┌ map(f::Base.var"#46#47", t::Tuple{Unsigned, UInt8}) @ Base ./tuple.jl:292
││││││││││││││││││││││┌ (::Base.var"#46#47")(x::UInt8) @ Base ./promotion.jl:418
│││││││││││││││││││││││┌ string(xs::Type{UInt8}) @ Base ./strings/io.jl:189
││││││││││││││││││││││││┌ print_to_string(xs::Type{UInt8}) @ Base ./strings/io.jl:148
│││││││││││││││││││││││││┌ print(io::IOBuffer, x::Type{UInt8}) @ Base ./strings/io.jl:35
││││││││││││││││││││││││││┌ show(io::IOBuffer, x::Type{UInt8}) @ Base ./show.jl:953
│││││││││││││││││││││││││││ runtime dispatch detected: Base._show_type(io::IOBuffer, x::Type{UInt8})::Nothing
││││││││││││││││││││││││││└────────────────────
││││││││││││││││││┌ promote(x::Unsigned, y::UInt8) @ Base ./promotion.jl:393
│││││││││││││││││││ runtime dispatch detected: Base._promote(x::Unsigned, y::UInt8)::Tuple{Any, Any}
││││││││││││││││││└────────────────────
││││││││││││││││││┌ promote(x::Unsigned, y::UInt8) @ Base ./promotion.jl:394
│││││││││││││││││││ runtime dispatch detected: Base.not_sametype(%4::Tuple{Unsigned, UInt8}, %5::Tuple{Any, Any})::Any
││││││││││││││││││└────────────────────
││││││││││││┌ string(n::Unsigned; base::Int64, pad::Int64) @ Base ./intfuncs.jl:846
│││││││││││││┌ hex(x::Unsigned, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:777
││││││││││││││┌ >>(x::Unsigned, c::UInt8) @ Base ./operators.jl:701
│││││││││││││││ runtime dispatch detected: (x::Unsigned >> 8)::Any
││││││││││││││└────────────────────
││││││││││││││┌ >>(x::Integer, c::UInt8) @ Base ./operators.jl:701
│││││││││││││││ runtime dispatch detected: (x::Integer >> 8)::Any
││││││││││││││└────────────────────
││││││││││││┌ string(n::Unsigned; base::Int64, pad::Int64) @ Base ./intfuncs.jl:848
│││││││││││││┌ _base(base::Int64, x::Integer, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:792
││││││││││││││┌ |(a::Integer, b::Bool) @ Base ./int.jl:1065
│││││││││││││││┌ promote_typeof(x::Integer, xs::Bool) @ Base ./promotion.jl:373
││││││││││││││││┌ promote_type(::Type{<:Integer}, ::Type{Bool}) @ Base ./promotion.jl:313
│││││││││││││││││┌ promote_result(::Type{<:Integer}, ::Type{Bool}, ::Type{T}, ::Type{S}) where {T, S<:Integer} @ Base ./promotion.jl:333
││││││││││││││││││ runtime dispatch detected: promote_type(%1::Type, %2::Type{S} where S<:Integer)::Any
│││││││││││││││││└────────────────────
│││││││││││││││┌ promote_typeof(x::Integer, xs::Bool) @ Base ./promotion.jl:373
││││││││││││││││ runtime dispatch detected: promote_type(%1::Type{<:Integer}, ::Bool)::Any
│││││││││││││││└────────────────────
│││││││││││││┌ _base(base::Int64, x::Integer, pad::Int64, neg::Bool) @ Base ./intfuncs.jl:796
││││││││││││││┌ kwcall(::@NamedTuple{base::Int64, pad::Int64}, ::typeof(ndigits), x::Integer) @ Base ./intfuncs.jl:700
│││││││││││││││┌ ndigits(x::Integer; base::Int64, pad::Int64) @ Base ./intfuncs.jl:700
││││││││││││││││┌ ndigits0z(x::Integer, b::Int64) @ Base ./intfuncs.jl:661
│││││││││││││││││┌ ndigits0zpb(x::BigInt, b::Int64) @ Base.GMP ./gmp.jl:813
││││││││││││││││││┌ ^(x::BigInt, y::Int64) @ Base.GMP ./gmp.jl:654
│││││││││││││││││││┌ bigint_pow(x::BigInt, y::Int64) @ Base.GMP ./gmp.jl:647
││││││││││││││││││││┌ (::Base.GMP.var"#throw1#3")(y::Int64) @ Base.GMP ./gmp.jl:632
│││││││││││││││││││││┌ string(::String, ::Int64, ::String) @ Base ./strings/io.jl:189
││││││││││││││││││││││ failed to optimize due to recursion: string(::String, ::Int64, ::String)
│││││││││││││││││││││└────────────────────
││││││││││││││││││││┌ (::Base.GMP.var"#throw1#3")(y::Int64) @────────────────────
...
┌ neighbors(d::Int64) @ Main c:\git\SPHExample\example\TempRepoCLL.jl:39
│ runtime dispatch detected: (%48::CartesianIndices{N, R} where {N, R<:Tuple{Vararg{UnitRange{Int64}, N}}})[%52::Any]::Any

```

116 (possible) errors from this?

Kind regards

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [February 20, 2024, 7:29am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/2 "2024-02-20T07:29:23Z")

</div>

Is `//` intentional? That makes a `Rational`.

---

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [February 20, 2024, 7:30am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/3 "2024-02-20T07:30:19Z")

</div>

I just want to index from `1:half_of_array` 🙂

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [February 20, 2024, 7:31am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/4 "2024-02-20T07:31:57Z")

</div>

Then try integer division, `÷` as an infix operator or `div` as function notation.

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [February 20, 2024, 7:32am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/5 "2024-02-20T07:32:06Z")

</div>

This function is type unstable because the type returned by `CartesianIndices(...)` carries the dimension (along with other things) as a type parameter and this cannot be inferred from the types of the function arguments.

---

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [February 20, 2024, 7:37am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/6 "2024-02-20T07:37:23Z")

</div>

> [@Benny](#):
>
> ÷

Thanks, using: `half_length = length(n_) ÷ 2 ` now

@abraemer then maybe it is a bad idea to use `CartesianIndices` all together? Will always have to find against it then I suppose?

Kind regards

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [February 20, 2024, 7:44am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/7 "2024-02-20T07:44:30Z")

</div>

> [@Ahmed\_Salih](#):
>
> @abraemer then maybe it is a bad idea to use `CartesianIndices` all together? Will always have to find against it then I suppose?

No. You just need to make its use typestable 🙂 E.g. you could pass in an array

```julia
function neighbors(array)
    n_ = CartesianIndices(array)
    n = n_[begin:end÷2]
end

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [February 20, 2024, 7:46am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/8 "2024-02-20T07:46:47Z")

</div>

The problem is the inability to infer the type of the output given the type of the input.

Right now the input type is `Int` but the output type is unclear since it depends on the _value_ of the argument rather than its type.

1. Rather than passing an `Int` you may want to pass a `Val` where the dimensionality is encoded in the type.

2. Rather than using `fill` consider using `ntuple` with a `Val` argument.

I will edit this later with concrete examples.

First let’s look at type inferrence.

```julia-repl
julia> @code_warntype neighbors(3)
MethodInstance for neighbors(::Int64)
  from neighbors(d::Int64) @ Main REPL[20]:1
Arguments
  #self#::Core.Const(neighbors)
  d::Int64 Locals
  n::Any
  n_::CartesianIndices{N, R} where {N, R<:Tuple{Vararg{UnitRange{Int64}, N}}}
Body::Any
1 ─ %1 = (-1:1)::Core.Const(-1:1)
│ %2 = Main.fill(%1, d)::Vector{UnitRange{Int64}}
│ %3 = Core._apply_iterate(Base.iterate, Core.tuple, %2)::Tuple{Vararg{UnitRange{Int64}}} │ (n_ = Main.CartesianIndices(%3))
│ %5 = n_::CartesianIndices{N, R} where {N, R<:Tuple{Vararg{UnitRange{Int64}, N}}}
│ %6 = Base.firstindex(n_)::Any
│ %7 = Base.lastindex(n_)::Integer
│ %8 = (%7 // 2)::Rational
│ %9 = (%6:%8)::Any
│ %10 = Base.getindex(%5, %9)::Any │ (n = %10)
└── return %10

```

If you run this yourself you will see a lot of red text indicating type instability. Ultimately, Julia gave up figuring out the return type and just went with `Any`.

If we implement my suggestions, the situation will be greatly improved.

```julia-repl
julia> function neighbors(v::Val{d}) where d
           n_ = CartesianIndices(ntuple(_->-1:1,v))
           return n_[begin:end÷2]
       end
neighbors (generic function with 2 methods)

julia> @code_warntype neighbors(Val(3))
MethodInstance for neighbors(::Val{3})
  from neighbors(v::Val{d}) where d @ Main REPL[28]:1
Static Parameters
  d = 3
Arguments
  #self#::Core.Const(neighbors)
  v::Core.Const(Val{3}())
Locals
  #5::var"#5#6"
  n_::CartesianIndices{3, Tuple{UnitRange{Int64}, UnitRange{Int64}, UnitRange{Int64}}}
Body::Vector{CartesianIndex{3}}
1 ─ (#5 = %new(Main.:(var"#5#6")))
│ %2 = #5::Core.Const(var"#5#6"())
│ %3 = Main.ntuple(%2, v)::Core.Const((-1:1, -1:1, -1:1))
│ (n_ = Main.CartesianIndices(%3))
│ %5 = n_::Core.Const(CartesianIndices((-1:1, -1:1, -1:1)))
│ %6 = Base.firstindex(n_::Core.Const(CartesianIndices((-1:1, -1:1, -1:1))))::Core.Const(1)
│ %7 = Base.lastindex(n_::Core.Const(CartesianIndices((-1:1, -1:1, -1:1))))::Core.Const(27)
│ %8 = (%7 ÷ 2)::Core.Const(13)
│ %9 = (%6:%8)::Core.Const(1:13)
│ %10 = Base.getindex(%5, %9)::Vector{CartesianIndex{3}}
└── return %10

```

Now we see that Julia can figure out that if the input is of type `Val{3}` then the output will be of type `Vector{CartesianIndex{3}}`.

That’s better, but I am noticing that we have allocated a whole `Vector`.

```julia-repl
julia> @time neighbors(Val(3))
  0.000008 seconds (1 allocation: 368 bytes)
13-element Vector{CartesianIndex{3}}:
 CartesianIndex(-1, -1, -1)
 CartesianIndex(0, -1, -1)
 CartesianIndex(1, -1, -1)
 CartesianIndex(-1, 0, -1)
 CartesianIndex(0, 0, -1)
 CartesianIndex(1, 0, -1)
 CartesianIndex(-1, 1, -1)
 CartesianIndex(0, 1, -1)
 CartesianIndex(1, 1, -1)
 CartesianIndex(-1, -1, 0)
 CartesianIndex(0, -1, 0)
 CartesianIndex(1, -1, 0)
 CartesianIndex(-1, 0, 0)

```

Instead we could just create a view of the `CartesianIndices`.

```julia-repl
julia> function neighbors(v::Val{d}) where d
           n_ = CartesianIndices(ntuple(_->-1:1,v))
           return @view n_[begin:end÷2]
       end
neighbors (generic function with 2 methods)

julia> @time neighbors(Val(3))
  0.000003 seconds
13-element view(reshape(::CartesianIndices{3, Tuple{UnitRange{Int64}, UnitRange{Int64}, UnitRange{Int64}}}, 27), 1:13) with eltype CartesianIndex{3}:
 CartesianIndex(-1, -1, -1)
 CartesianIndex(0, -1, -1)
 CartesianIndex(1, -1, -1)
 CartesianIndex(-1, 0, -1)
 CartesianIndex(0, 0, -1)
 CartesianIndex(1, 0, -1)
 CartesianIndex(-1, 1, -1)
 CartesianIndex(0, 1, -1)
 CartesianIndex(1, 1, -1)
 CartesianIndex(-1, -1, 0)
 CartesianIndex(0, -1, 0)
 CartesianIndex(1, -1, 0)
 CartesianIndex(-1, 0, 0)

```

What the function returns acts the same as the `Vector`, but no memory is allocated!

```julia-repl
julia> cis = neighbors(Val(3));

julia> cis[5]
CartesianIndex(0, 0, -1)

```

To maintain your original function signature, you can add the following method.

```julia-repl
julia> neighbors(d::Int) = neighbors(Val(d))
neighbors (generic function with 2 methods)

julia> @code_warntype neighbors(3)
MethodInstance for neighbors(::Int64)
  from neighbors(d::Int64) @ Main REPL[41]:1
Arguments
  #self#::Core.Const(neighbors)
  d::Int64
Body::Any
1 ─ %1 = Main.Val(d)::Val
│ %2 = Main.neighbors(%1)::Any └── return %2

```

We see that type inferrence is still problematic. However something interesting occurs if we create a simple function wirh a known dimension.

```julia-repl
julia> f() = neighbors(3)
f (generic function with 2 methods)

julia> @code_warntype f()
MethodInstance for f()
  from f() @ Main REPL[43]:1
Arguments
  #self#::Core.Const(f)
Body::SubArray{CartesianIndex{3}, 1, Base.ReshapedArray{CartesianIndex{3}, 1, CartesianIndices{3, Tuple{UnitRange{Int64}, UnitRange{Int64}, UnitRange{Int64}}}, Tuple{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}, Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}}}, Tuple{UnitRange{Int64}}, false}
1 ─ %1 = Main.neighbors(3)::Core.Const(CartesianIndex{3}[CartesianIndex(-1, -1, -1), CartesianIndex(0, -1, -1), CartesianIndex(1, -1, -1), CartesianIndex(-1, 0, -1), CartesianIndex(0, 0, -1), CartesianIndex(1, 0, -1), CartesianIndex(-1, 1, -1), CartesianIndex(0, 1, -1), CartesianIndex(1, 1, -1), CartesianIndex(-1, -1, 0), CartesianIndex(0, -1, 0), CartesianIndex(1, -1, 0), CartesianIndex(-1, 0, 0)])
└── return %1

```

Here we have taken advantage of constant propagation. Julia figured out that `3` is a constant and was able to do type inferrence.

---

<div class="post-metadata">

**Author:** ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)\
**Post date:** [February 20, 2024, 8:04am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/9 "2024-02-20T08:04:48Z")

</div>

> [@mkitti](#):
>
> ```julia
> function neighbors(v::Val{d}) where d
> n_ = CartesianIndices(ntuple(_->-1:1,v))
> return n_[begin:end÷2]
> end
> 
> ```

Thanks!

That seems to have entirely resolved it. I suppose there is not anyway to make the `Val` implicit, so that I can write `neighbors(2)` again?

First time I see `Val` and understand why it is useful at the same time. Thanks a ton!

I am fine with it being a bit confusing, just ease of personal use.

Kind regards

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [February 20, 2024, 8:17am UTC](https://discourse.julialang.org/t/why-does-indexing-into-cartesianindices-lead-to-excessive-runtime-dispatch/110438/10 "2024-02-20T08:17:31Z")

</div>

> [@Ahmed\_Salih](#):
>
> That seems to have entirely resolved it. I suppose there is not anyway to make the `Val` implicit, so that I can write `neighbors(2)` again?

As you can see from the end of my edited post, we can add it, but we encounter the same issue as in the original case. The exception is if the integer is a constant or a type parameter.

Let’s say we have an image where we know the type. In this case we know thr array has e dimensions. That can also be propagated through.

```julia-repl
julia> img = rand(0:9, (3,3,3))
3×3×3 Array{Int64, 3}:
[:, :, 1] =
 5 1 0
 7 5 8
 4 4 4

[:, :, 2] =
 6 1 8
 1 2 3
 2 9 4

[:, :, 3] =
 4 0 5
 1 0 2
 9 4 8

julia> neighbors(::AbstractArray{<: Any, N}) where N =
           neighbors(N)
neighbors (generic function with 3 methods)

julia> @code_warntype neighbors(img)
MethodInstance for neighbors(::Array{Int64, 3})
  from neighbors(::AbstractArray{<:Any, N}) where N @ Main REPL[52]:1
Static Parameters
  N = 3
Arguments
  #self#::Core.Const(neighbors)
  _::Array{Int64, 3}
Body::SubArray{CartesianIndex{3}, 1, Base.ReshapedArray{CartesianIndex{3}, 1, CartesianIndices{3, Tuple{UnitRange{Int64}, UnitRange{Int64}, UnitRange{Int64}}}, Tuple{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}, Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}}}, Tuple{UnitRange{Int64}}, false}
1 ─ %1 = Main.neighbors($(Expr(:static_parameter, 1)))::Core.Const(CartesianIndex{3}[CartesianIndex(-1, -1, -1), CartesianIndex(0, -1, -1), CartesianIndex(1, -1, -1), CartesianIndex(-1, 0, -1), CartesianIndex(0, 0, -1), CartesianIndex(1, 0, -1), CartesianIndex(-1, 1, -1), CartesianIndex(0, 1, -1), CartesianIndex(1, 1, -1), CartesianIndex(-1, -1, 0), CartesianIndex(0, -1, 0), CartesianIndex(1, -1, 0), CartesianIndex(-1, 0, 0)])

```
