I know this is not replying to your original question but it might be 
relevant or not.

There was a suggestion for speeding up dispatch of abstract types in 
another julia-users discussion: dispatch slowdown when iterating over array 
with abstract values 
<https://groups.google.com/forum/#!topic/julia-users/OBs0fmNmjCU>.
In your case, the idea was to use a manual case/select statement:

if isa(y.x, UInt64)
    s += sqrt(y.x::UInt64)
elseif isa(y.x, UInt32)
    s += sqrt(y.x::UInt32)
elseif
    ...
end



I wrote a (rather crude) macro to generate similar code. You could use it 
in your case as follows:
 
function flog2(y)
    s = 0.0
    for i=1:1000000
        @DynamicDispatch y.x::Unsigned begin
            s += sqrt(y.x)
        end
    end
    s
end


I guess you can read this as "for all T in Unsigned generate if (isa(y.x, 
T) s += sqrt(y.x::T)"

flog2 should run faster and without allocation.

Of course this is not super clean, but if performance is a priority it may 
be of use.


And here's the macro.
Not fully tested or recommended, but you may be able to model something 
from it.

isdefined(:__precompile__) && __precompile__()

module DynamicDispatchUtilities
export  ConcreteSubtypes,
        TransformExpr,
        @DynamicDispatch

function ConcreteSubtypes(T::DataType)
    types = DataType[]
    if isleaftype(T)
        push!(types, T)
    else
        for S in subtypes(T)
            if S != T   # guard against infinite recursion, Any is a 
subtype of itself
                append!(types, ConcreteSubtypes(S))
            end
        end
    end
    return types
end

function TransformExpr(x, e1, e2)
    y = copy(x)
    if x == e1
        y = e2
    elseif isa(x, Expr)
        for i = 1:length(x.args)
            y.args[i] = TransformExpr(x.args[i], e1, e2)
        end
    end
    return y
end

macro DynamicDispatch(var, expr)
    # var should be of form e::A, where e is a symbol/reference and A is an 
abstract type
    @assert isa(var, Expr) && var.head == :(::)
    e = var.args[1]
    A = var.args[2]
    concrete_types = ConcreteSubtypes(eval(current_module(), A))
    C = concrete_types[end]
    case_block = TransformExpr(expr, e, :($e::$C))
    for i = length(concrete_types)-1 : -1 : 1
        C = concrete_types[i]
        case_block = Expr(:if, :(isa($e,$C)), TransformExpr(expr, e, 
:($e::$C)), case_block)
    end
    return esc(case_block)
end
end



Reply via email to