Skip to content

Commit f9db5d9

Browse files
committed
Reduce number of getindex(::Type, ...) methods
Previously, there were special cases for `T[]`, `T[a]`, `T[a,b]` and `T[a,b,c]`. Together with the general case for more elements, that meant five methods to consider in cases like `T[x...]` where the length of `x` was not known at compile time. That was beyond the inference limit and such a call would be inferred as `Any`. So this change gets rid of all the special cases. The loop-based general case worked well if all arguments were of the same type, but otherwise suffered from type-instability inside the loop. Without the special cases for low element count this would be hit more often, so for the non-homogenous case, the loop is replaced with a call to `afoldl` that basically unrolls the loop for up to 32 elements.
1 parent 1a3da30 commit f9db5d9

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

base/array.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -402,17 +402,20 @@ julia> getindex(Int8, 1, 2, 3)
402402
"""
403403
function getindex(::Type{T}, vals...) where T
404404
a = Vector{T}(undef, length(vals))
405-
@inbounds for i = 1:length(vals)
406-
a[i] = vals[i]
405+
if vals isa NTuple
406+
@inbounds for i in 1:length(vals)
407+
a[i] = vals[i]
408+
end
409+
else
410+
# use afoldl to avoid type instability inside loop
411+
afoldl(1, vals...) do i, v
412+
@inbounds a[i] = v
413+
return i + 1
414+
end
407415
end
408416
return a
409417
end
410418

411-
getindex(::Type{T}) where {T} = (@inline; Vector{T}())
412-
getindex(::Type{T}, x) where {T} = (@inline; a = Vector{T}(undef, 1); @inbounds a[1] = x; a)
413-
getindex(::Type{T}, x, y) where {T} = (@inline; a = Vector{T}(undef, 2); @inbounds (a[1] = x; a[2] = y); a)
414-
getindex(::Type{T}, x, y, z) where {T} = (@inline; a = Vector{T}(undef, 3); @inbounds (a[1] = x; a[2] = y; a[3] = z); a)
415-
416419
function getindex(::Type{Any}, @nospecialize vals...)
417420
a = Vector{Any}(undef, length(vals))
418421
@inbounds for i = 1:length(vals)

test/arrayops.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2318,10 +2318,12 @@ let A = zeros(Int, 2, 2), B = zeros(Float64, 2, 2)
23182318
f40() = Float64[A A]
23192319
f41() = [A B]
23202320
f42() = Int[A B]
2321+
f43() = Int[A...]
2322+
f44() = Float64[A..., B...]
23212323

23222324
for f in [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16,
23232325
f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
2324-
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42]
2326+
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42, f43, f44]
23252327
@test isconcretetype(Base.return_types(f, ())[1])
23262328
end
23272329
end

0 commit comments

Comments
 (0)