On Fri, May 29, 2015 at 5:32 PM, Yichao Yu <[email protected]> wrote:
> On Fri, May 29, 2015 at 3:50 PM, Seth <[email protected]> wrote:
>> I have an function that takes an optional (potentially very large) matrix
>> (AbstractArray{Float64,2}). I'd like to create a parameter to the function
>> that's EITHER this array, or a boolean (false). If I define
>>
>> edge_dists::Union(Bool, AbstractArray{Float64,2}) = false
>>
>>
>>
>> in my function declaration, would that cause significant performance
>> penalties when accessing the parameter?
>
> The function will specialize on (the type of) this parameter so there
> shouldn't be a big penalty. If you need to do something different when
> this parameter is missing and if the two cases shares a lot of code,
> this might not be a bad idea (although IMHO ::Union(Void,
> AbstractArray{Float64, 2})=nothing might be more intuitive)
This is assuming that the behavior of the function are similar in both
cases. The type inference is not smart enough to to constant
propagation and branch prediction yet (@carnaval) so in the following
simple example, it would be better to just write two functions.
```
julia> f(a::Union(Void, Vector{Int})=nothing) = a === nothing ? 1.0 : length(a)
f (generic function with 2 methods)
julia> @code_warntype f()
Variables:
_var0::Any
Body:
begin # none, line 1:
GenSym(0) = nothing
unless GenSym(0) === nothing::Bool goto 1
_var0 = 1.0
goto 2
1:
_var0 = length(GenSym(0))::Any
2:
return _var0
end::Any
julia> @code_warntype f([1])
Variables:
a::Array{Int64,1}
Body:
begin # none, line 1:
unless a::Array{Int64,1} === nothing::Bool goto 0
return 1.0
0:
return (top(arraylen))(a::Array{Int64,1})::Int64
end::Union(Float64,Int64)
```