function myhypot(x::Number...)
s = sum(abs2, float.(x))
r = sqrt(s)
if isnan(s) || isinf(s) || s ≤ floatmin(s) * (length(x) - 1)
println("here")
any(isinf, x) && return oftype(r, Inf)
ma = maximum(abs.(x))
iszero(ma) && return oftype(r, ma)
return oftype(r, ma * sqrt(sum(abs2, x ./ ma)))
else
return r
end
end
function h(x::Number...)
s = sum(abs2, float.(x))
r = sqrt(s)
return r
end
The two functions are equivalent if the branch condition is not met. I added a println statement to make sure that this branch was not being executed.
Here is an example where the branch is not entered. However I get very different allocations:
function myhypot(x::Number...)
s = sum(abs2, float.(x))
r = sqrt(s)
if isnan(s) || isinf(s) || isinf(s)
isinf.(x)
return r
else
return r
end
end
julia> @btime myhypot(4.,5.,6.,7.)
1.365 μs (12 allocations: 384 bytes)
11.224972160321824
function myhypot(x::Number...)
s = sum(abs2, float.(x))
r = sqrt(s)
if isnan(s) || isinf(s)
isinf.(x)
return r
else
return r
end
end
julia> @btime myhypot(4.,5.,6.,7.)
4.254 ns (0 allocations: 0 bytes)
11.224972160321824
function myhypot(x::Number...)
s = sum(abs2, float.(x))
r = sqrt(s)
if isnan(s) || isinf(s) || isinf(s)
return r
else
return r
end
end
julia> @btime myhypot(4.,5.,6.,7.)
3.783 ns (0 allocations: 0 bytes)
11.224972160321824
Not sure what fixed it, but it no longer happens on master:
julia> function myhypot(x::Number...)
s = sum(abs2, float.(x))
r = sqrt(s)
if isnan(s) || isinf(s) || isinf(s)
isinf.(x)
return r
else
return r
end
end
myhypot (generic function with 1 method)
julia> @btime myhypot(4.,5.,6.,7.)
5.025 ns (0 allocations: 0 bytes)
11.224972160321824
For some reason the splatting penalty seems to be kicking in very early in this case. If you replace the splatted argument x with four positional arguments and recreate the tuple x inside the function, there is no performance problem. If you make the argument x a tuple, things are also fine.