Hi Tim,
My recommendation would be to code up your first example (at least) and see
where the bottlenecks actually are.
It certainly is true that iterating over an array of abstract values is
almost always slower than iterating over an array of the same type.
But it could also be true that any slowdown from that iteration is
inconsequential compared to the feature calculations themselves, and that
the convenience of multiple dispatch makes it easier to code up new
features. It really depends on the actual data and features you're
targeting with this code.
Oh, and dispatching on `Val{1}`, etc., probably won't buy you much after
you code up a few features (or maybe at all), since a lot of the time spent
inside of a loop will be spent doing dynamic dispatch. It seems that
you'll probably have to pay that cost no matter the implementation.
Cheers,
Kevin
On Mon, Jul 11, 2016 at 12:14 PM, Tim Wheeler <[email protected]>
wrote:
> Hello Julia Users,
>
> I have wanted to use dispatch to enable the extraction of features or
> metrics. This way you can define a large collection of features that all
> extend AbstractFeature, and then just run through a list of them to get
> your feature vector.
>
> One way this could be implemented is as follows:
>
> abstract AbstractFeature
> extract(f::AbstractFeature, ::State) = error("extract not implemented for
> AbstractFeature $f)
>
> type FeatureA <: AbstractFeature end
> extract(f::FeatureA, s::State) = 1.0
>
> type FeatureB <: AbstractFeature end
> extract(f::FeatureB, s::State) = 2.0
>
> ...
>
>
> This is great in theory, but in practice you end up having to iterate over
> an abstract array, ::Vector{AbstractFeature}, which is slow.
>
> Other options include only having one Feature type:
> type Feature
> id::Int
> end
>
> function extract(f::Feature, s::State)
> if f.id == 1
> # code for feature 1...
> elseif f.id == 2
> # code for feature 2...
> elseif ...
> end
> end
>
> You lose the ability to define Features with different internal fields /
> parameters.
>
> I was thinking you can also dispatch on the internal id value. Would this
> work?
>
> type Feature
> id::Int
> end
> extract(::Type{Val{1}}, s::State) = 1.0
> extract(::Type{Val{2}}, s::State) = 2.0
>
> This is a little annoying because the ids are non-intuitive and you have
> to ensure there is no collision when you define new ones.
>
> Any ideas / recommendations?
>
>
>