Skip to content

Commit 4b739e7

Browse files
authored
Isolate string interpolation in error paths for sparse matrix constructors (#38446)
This provides a better-than-3x speed improvement for `spzeros(5, 5)`: julia> @Btime spzeros(5, 5); 341.371 ns (3 allocations: 288 bytes) julia> Revise.track(SparseArrays) julia> @Btime spzeros(5, 5); 103.633 ns (3 allocations: 288 bytes)
1 parent a7168a5 commit 4b739e7

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

stdlib/SparseArrays/src/sparsematrix.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,29 @@ function sparse_check_Ti(m::Integer, n::Integer, Ti::Type)
5353
end
5454

5555
function sparse_check(n::Integer, colptr::Vector{Ti}, rowval, nzval) where Ti
56+
# String interpolation is a performance bottleneck when it's part of the same function,
57+
# ensure we only do it once committed to the error.
58+
throwstart(ckp) = throw(ArgumentError("$ckp == colptr[1] != 1"))
59+
throwmonotonic(ckp, ck, k) = throw(ArgumentError("$ckp == colptr[$(k-1)] > colptr[$k] == $ck"))
60+
5661
sparse_check_length("colptr", colptr, n+1, String) # don't check upper bound
5762
ckp = Ti(1)
58-
ckp == colptr[1] || throw(ArgumentError("$ckp == colptr[1] != 1"))
63+
ckp == colptr[1] || throwstart(ckp)
5964
@inbounds for k = 2:n+1
6065
ck = colptr[k]
61-
ckp <= ck || throw(ArgumentError("$ckp == colptr[$(k-1)] > colptr[$k] == $ck"))
66+
ckp <= ck || throwmonotonic(ckp, ck, k)
6267
ckp = ck
6368
end
6469
sparse_check_length("rowval", rowval, ckp-1, Ti)
6570
sparse_check_length("nzval", nzval, 0, Ti) # we allow empty nzval !!!
6671
end
6772
function sparse_check_length(rowstr, rowval, minlen, Ti)
73+
throwmin(len, minlen, rowstr) = throw(ArgumentError("$len == length($rowstr) < $minlen"))
74+
throwmax(len, max, rowstr) = throw(ArgumentError("$len == length($rowstr) >= $max"))
75+
6876
len = length(rowval)
69-
len >= minlen || throw(ArgumentError("$len == length($rowstr) < $minlen"))
70-
!isbitstype(Ti) || len < typemax(Ti) ||
71-
throw(ArgumentError("$len == length($rowstr) >= $(typemax(Ti))"))
77+
len >= minlen || throwmin(len, minlen, rowstr)
78+
!isbitstype(Ti) || len < typemax(Ti) || throwmax(len, typemax(Ti), rowstr)
7279
end
7380

7481
size(S::SparseMatrixCSC) = (getfield(S, :m), getfield(S, :n))

0 commit comments

Comments
 (0)