Skip to content

Commit 322e111

Browse files
timholyKristofferC
authored andcommitted
Improve (no)specialization in print_matrix (JuliaLang#39194)
It makes sense to extract the axes before we lose inferrability of the vector or matrix being printed. Hence this delays application of `@nospecialize`. However, it also standardizes the row/column indices and reduces specialization in `alignment`. Co-authored-by: Kristoffer Carlsson <[email protected]>
1 parent 2ff55d0 commit 322e111

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

base/arrayshow.jl

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Parameter `sep::Integer` is number of spaces to put between elements.
5757
Alignment is reported as a vector of (left,right) tuples, one for each
5858
column going across the screen.
5959
"""
60-
function alignment(io::IO, X::AbstractVecOrMat,
60+
function alignment(io::IO, @nospecialize(X::AbstractVecOrMat),
6161
rows::AbstractVector{T}, cols::AbstractVector{V},
6262
cols_if_complete::Integer, cols_otherwise::Integer, sep::Integer) where {T,V}
6363
a = Tuple{T, V}[]
@@ -94,7 +94,7 @@ is specified as string sep.
9494
`print_matrix_row` will also respect compact output for elements.
9595
"""
9696
function print_matrix_row(io::IO,
97-
X::AbstractVecOrMat, A::Vector,
97+
@nospecialize(X::AbstractVecOrMat), A::Vector,
9898
i::Integer, cols::AbstractVector, sep::AbstractString)
9999
for (k, j) = enumerate(cols)
100100
k > length(A) && break
@@ -158,16 +158,15 @@ string post (printed at the end of the last row of the matrix).
158158
Also options to use different ellipsis characters hdots, vdots, ddots.
159159
These are repeated every hmod or vmod elements.
160160
"""
161-
function print_matrix(io::IO, @nospecialize(X::AbstractVecOrMat),
161+
function print_matrix(io::IO, X::AbstractVecOrMat,
162162
pre::AbstractString = " ", # pre-matrix string
163163
sep::AbstractString = " ", # separator between elements
164164
post::AbstractString = "", # post-matrix string
165165
hdots::AbstractString = " \u2026 ",
166166
vdots::AbstractString = "\u22ee",
167167
ddots::AbstractString = " \u22f1 ",
168168
hmod::Integer = 5, vmod::Integer = 5)
169-
# use invokelatest to avoid backtracing in type invalidation, ref #37741
170-
invokelatest(_print_matrix, io, X, pre, sep, post, hdots, vdots, ddots, hmod, vmod, unitrange(axes(X,1)), unitrange(axes(X,2)))
169+
_print_matrix(io, inferencebarrier(X), pre, sep, post, hdots, vdots, ddots, hmod, vmod, unitrange(axes(X,1)), unitrange(axes(X,2)))
171170
end
172171

173172
function _print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA, colsA)
@@ -191,12 +190,16 @@ function _print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, h
191190
halfheight = div(screenheight,2)
192191
if m > screenheight
193192
rowsA = [rowsA[(0:halfheight-1) .+ firstindex(rowsA)]; rowsA[(end-div(screenheight-1,2)+1):end]]
193+
else
194+
rowsA = [rowsA;]
194195
end
195196
# Similarly for columns, only necessary to get alignments for as many
196197
# columns as could conceivably fit across the screen
197198
maxpossiblecols = div(screenwidth, 1+sepsize)
198199
if n > maxpossiblecols
199200
colsA = [colsA[(0:maxpossiblecols-1) .+ firstindex(colsA)]; colsA[(end-maxpossiblecols+1):end]]
201+
else
202+
colsA = [colsA;]
200203
end
201204
A = alignment(io, X, rowsA, colsA, screenwidth, screenwidth, sepsize)
202205
# Nine-slicing is accomplished using print_matrix_row repeatedly
@@ -268,12 +271,15 @@ end
268271

269272
# typeinfo agnostic
270273
# n-dimensional arrays
271-
function show_nd(io::IO, a::AbstractArray, print_matrix::Function, label_slices::Bool)
274+
show_nd(io::IO, a::AbstractArray, print_matrix::Function, label_slices::Bool) =
275+
_show_nd(io, inferencebarrier(a), print_matrix, label_slices, map(unitrange, axes(a)))
276+
277+
function _show_nd(io::IO, @nospecialize(a::AbstractArray), print_matrix::Function, label_slices::Bool, axs::Tuple{Vararg{AbstractUnitRange}})
272278
limit::Bool = get(io, :limit, false)
273279
if isempty(a)
274280
return
275281
end
276-
tailinds = tail(tail(axes(a)))
282+
tailinds = tail(tail(axs))
277283
nd = ndims(a)-2
278284
for I in CartesianIndices(tailinds)
279285
idxs = I.I
@@ -284,7 +290,7 @@ function show_nd(io::IO, a::AbstractArray, print_matrix::Function, label_slices:
284290
if length(ind) > 10
285291
if ii == ind[firstindex(ind)+3] && all(d->idxs[d]==first(tailinds[d]),1:i-1)
286292
for j=i+1:nd
287-
szj = length(axes(a, j+2))
293+
szj = length(axs[j+2])
288294
indj = tailinds[j]
289295
if szj>10 && first(indj)+2 < idxs[j] <= last(indj)-3
290296
@goto skip
@@ -302,7 +308,7 @@ function show_nd(io::IO, a::AbstractArray, print_matrix::Function, label_slices:
302308
if label_slices
303309
_show_nd_label(io, a, idxs)
304310
end
305-
slice = view(a, axes(a,1), axes(a,2), idxs...)
311+
slice = view(a, axs[1], axs[2], idxs...)
306312
print_matrix(io, slice)
307313
print(io, idxs == map(last,tailinds) ? "" : "\n\n")
308314
@label skip
@@ -379,10 +385,13 @@ end
379385
`_show_nonempty(io, X::AbstractMatrix, prefix)` prints matrix X with opening and closing square brackets,
380386
preceded by `prefix`, supposed to encode the type of the elements.
381387
"""
382-
function _show_nonempty(io::IO, X::AbstractMatrix, prefix::String)
388+
_show_nonempty(io::IO, X::AbstractMatrix, prefix::String) =
389+
_show_nonempty(io, inferencebarrier(X), prefix, axes(X))
390+
391+
function _show_nonempty(io::IO, @nospecialize(X::AbstractMatrix), prefix::String, axs::Tuple{AbstractUnitRange,AbstractUnitRange})
383392
@assert !isempty(X)
384393
limit = get(io, :limit, false)::Bool
385-
indr, indc = axes(X,1), axes(X,2)
394+
indr, indc = axs
386395
nr, nc = length(indr), length(indc)
387396
rdots, cdots = false, false
388397
rr1, rr2 = unitrange(indr), 1:0

0 commit comments

Comments
 (0)