-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Open
Labels
performanceMust go fasterMust go faster
Description
There are places in Base where manually outlining error throwing can give significant (relative) speedups. For example, changing
Lines 7 to 15 in bdd0e99
| function parse(::Type{T}, c::Char, base::Integer=36) where T<:Integer | |
| a::Int = (base <= 36 ? 10 : 36) | |
| 2 <= base <= 62 || throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base")) | |
| d = '0' <= c <= '9' ? c-'0' : | |
| 'A' <= c <= 'Z' ? c-'A'+10 : | |
| 'a' <= c <= 'z' ? c-'a'+a : throw(ArgumentError("invalid digit: $(repr(c))")) | |
| d < base || throw(ArgumentError("invalid base $base digit $(repr(c))")) | |
| convert(T, d) | |
| end |
function parse2(::Type{T}, c::Char, base::Integer=36) where T<:Integer
a::Int = (base <= 36 ? 10 : 36)
2 <= base <= 62 || throw_invalid_base(base)
d = '0' <= c <= '9' ? c-'0' :
'A' <= c <= 'Z' ? c-'A'+10 :
'a' <= c <= 'z' ? c-'a'+a : throw_invalid_digit(c)
d < base || throw_invalid_base_digit(base, c)
convert(T, d)
end
@noinline throw_invalid_base(base) = throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base"))
@noinline throw_invalid_digit(c) = throw(ArgumentError("invalid digit: $(repr(c))"))
@noinline throw_invalid_base_digit(base, c) = throw(ArgumentError("invalid base $base digit $(repr(c))"))has a measurable impact:
julia> @btime parse2(Int64, 'a', 36);
3.864 ns (0 allocations: 0 bytes)
julia> @btime parse(Int64, 'a', 36);
5.422 ns (0 allocations: 0 bytes)
Is it worth to go through these type of functions and manually outline the error throwing, or is the plan to deal with all of that in another way which does not require manually moving them out?
musm and ronisbr
Metadata
Metadata
Assignees
Labels
performanceMust go fasterMust go faster