Skip to content

Commit

Permalink
Experiment with removing dicts type parameter, slows down getindex ~ 2x
Browse files Browse the repository at this point in the history
  • Loading branch information
davidavdav committed Jun 18, 2018
1 parent 0c95278 commit 85af84c
Show file tree
Hide file tree
Showing 11 changed files with 28 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/arithmetic.jl
Expand Up @@ -188,7 +188,7 @@ function lufact!{T}(n::NamedArray{T}, pivot::Union{Type{Val{false}}, Type{Val{tr
end

## after lu.jl, this could be merged at Base.
function Base.getindex(A::LU{T,NamedArray{T,2,AT,DT}}, d::Symbol) where {T, AT, DT}
function Base.getindex(A::LU{T,NamedArray{T,2,AT}}, d::Symbol) where {T, AT}
m, n = size(A)
if d == :L
L = tril!(A.factors[1:m, 1:min(m,n)])
Expand Down
4 changes: 2 additions & 2 deletions src/base.jl
Expand Up @@ -7,7 +7,7 @@

## copy
import Base: copy, copy!
copy{T,N,AT,DT}(a::NamedArray{T,N,AT,DT}) = NamedArray{T,N,AT,DT}(copy(a.array), deepcopy(a.dicts), identity(a.dimnames))
copy(a::NamedArray{T,N,AT}) where {T, N, AT} = NamedArray{T,N,AT}(copy(a.array), deepcopy(a.dicts), identity(a.dimnames))

## from array.jl
function copy!{T}(dest::NamedArray{T}, dsto::Integer, src::ArrayOrNamed{T}, so::Integer, N::
Expand Down Expand Up @@ -44,7 +44,7 @@ function Base.similar{T,N}(n::NamedArray{T,N}, t::Type, dims::Base.Dims)
end
tdicts = tuple(dicts...)
array = similar(n.array, t, dims)
return NamedArray{t,N,typeof(array),typeof(tdicts)}(array, tdicts, tuple(dimnames...))
return NamedArray{t,N,typeof(array)}(array, tdicts, tuple(dimnames...))
end

## our own interpretation of ind2sub
Expand Down
2 changes: 1 addition & 1 deletion src/changingnames.jl
Expand Up @@ -12,7 +12,7 @@ for f = (:sum, :prod, :maximum, :minimum, :mean, :std, :var)
@eval function ($f){T,N}(a::NamedArray{T,N}, d::Dims)
s = ($f)(a.array, d)
dicts = tuple([issubset(i,d) ? OrderedDict(string($f,"(",a.dimnames[i],")") => 1) : a.dicts[i] for i=1:ndims(a)]...)
NamedArray{T,N,typeof(a.array), typeof(dicts)}(s, dicts, a.dimnames)
NamedArray{T,N,typeof(a.array)}(s, dicts, a.dimnames)
end
@eval ($f)(a::NamedArray, d::Int) = ($f)(a, (d,))
end
Expand Down
6 changes: 3 additions & 3 deletions src/constructors.jl
Expand Up @@ -25,13 +25,13 @@ NamedArray{T,N}(a::AbstractArray{T,N}, names::Tuple{}) = NamedArray{T,N,typeof(a
## Basic constructor: array, tuple of dicts
## dimnames created as default, then inner constructor called
function NamedArray{T,N}(array::AbstractArray{T,N}, names::NTuple{N,OrderedDict})
NamedArray{T, N, typeof(array), typeof(names)}(array, names, defaultdimnames(array)) ## inner constructor
NamedArray{T, N, typeof(array)}(array, names, defaultdimnames(array)) ## inner constructor
end

## constructor with array, names and dimnames (dict is created from names)
function NamedArray{T,N}(array::AbstractArray{T,N}, names::NTuple{N,Vector}, dimnames::NTuple{N, Any}=defaultdimnames(array))
dicts = defaultnamesdict(names)
NamedArray{T, N, typeof(array), typeof(dicts)}(array, dicts, dimnames)
NamedArray{T, N, typeof(array)}(array, dicts, dimnames)
end

## vectors instead of tuples, with defaults (incl. no names or dimnames at all)
Expand All @@ -46,7 +46,7 @@ function NamedArray{T,N,VT}(array::AbstractArray{T,N},
else
dicts = defaultnamesdict(tuple(names...))::NTuple{N, OrderedDict{eltype(VT),Int}}
end
NamedArray{T, N, typeof(array), typeof(dicts)}(array, dicts, tuple(dimnames...))
NamedArray{T, N, typeof(array)}(array, dicts, tuple(dimnames...))
end


Expand Down
12 changes: 6 additions & 6 deletions src/index.jl
Expand Up @@ -7,16 +7,16 @@
import Base: getindex, setindex!

## AbstractArray Interface, integers have precedence over everything else
getindex(n::NamedArray{T, N, AT, DT}, i::Int) where {T, N, AT, DT} = getindex(n.array, i)
getindex(n::NamedArray{T, N, AT, DT}, I::Vararg{Int, N}) where {T, N, AT, DT} = getindex(n.array, I...)
setindex!(n::NamedArray{T, N, AT, DT}, v, i::Int) where {T, N, AT, DT} = setindex!(n.array, v, i::Int)
setindex!(n::NamedArray{T, N, AT, DT}, v, I::Vararg{Int, N}) where {T, N, AT, DT} = setindex!(n.array, v, I...)
getindex(n::NamedArray{T, N, AT}, i::Int) where {T, N, AT} = getindex(n.array, i)
getindex(n::NamedArray{T, N, AT}, I::Vararg{Int, N}) where {T, N, AT} = getindex(n.array, I...)
setindex!(n::NamedArray{T, N, AT}, v, i::Int) where {T, N, AT} = setindex!(n.array, v, i::Int)
setindex!(n::NamedArray{T, N, AT}, v, I::Vararg{Int, N}) where {T, N, AT} = setindex!(n.array, v, I...)
## optional methods
Base.IndexStyle(n::NamedArray) = IndexStyle(n.array)

## Ambiguity
#getindex(n::NamedArray{T, 1, AT, DT}, i::Int64) where {T, AT, DT} = getindex(n.array, i)
setindex!(n::NamedArray{T, 1, AT, DT}, v::Any, i::Int64) where {T, AT, DT} = setindex!(n.array, v, i)
#setindex!(n::NamedArray{T, 1, AT}, v::Any, i::Int64) where {T, AT} = setindex!(n.array, v, i)

function flattenednames(n::NamedArray)
L = length(n) # elements in array
Expand All @@ -39,7 +39,7 @@ getindex(n::NamedArray, ::Colon) = NamedArray(n.array[:], [flattenednames(n)] ,
## special 0-dimensional case
## getindex{T}(n::NamedArray{T,0}, i::Real) = getindex(n.array, i)

getindex(n::NamedArray{T, N, AT, DT}, I::Vararg{Any,N}) where {T, N, AT, DT} = namedgetindex(n, map((d,i)->indices(d, i), n.dicts, I)...)
getindex(n::NamedArray{T, N, AT}, I::Vararg{Any,N}) where {T, N, AT} = namedgetindex(n, map((d,i)->indices(d, i), n.dicts, I)...)

Base.view{T,N}(n::NamedArray{T,N}, I::Vararg{Union{AbstractArray,Colon,Real},N}) = namedgetindex(n, map((d,i)->indices(d, i), n.dicts, I)...; useview=true)
Base.view{T,N}(n::NamedArray{T,N}, I::Vararg{Any,N}) = namedgetindex(n, map((d,i)->indices(d, i), n.dicts, I)...; useview=true)
Expand Down
4 changes: 2 additions & 2 deletions src/keepnames.jl
Expand Up @@ -64,7 +64,7 @@ end
if isdefined(Base.Broadcast, :broadcast_c)
array(n::NamedArray) = n.array
array(a) = a
function dictstype{T,N,AT,DT,M}(n::NamedArray{T,N,AT,DT}, ::Type{Val{M}})
function dictstype{T,N,AT,M}(n::NamedArray{T,N,AT}, ::Type{Val{M}})
N > M && error("Cannot truncate array")
return tuple(n.dicts..., fill(nothing, M - N)...)::NTuple{M, Any}
end
Expand All @@ -86,7 +86,7 @@ if isdefined(Base.Broadcast, :broadcast_c)
AT = typeof(res)
## is there a NamedArray with the same dimensions?
for a in As
isa(a, NamedArray) && size(a) == size(res) && return NamedArray{T, N, AT, typeof(a.dicts)}(res, a.dicts, a.dimnames)
isa(a, NamedArray) && size(a) == size(res) && return NamedArray{T, N, AT}(res, a.dicts, a.dimnames)
end
## can we collect the dimensions from individual namedarrays?
dicts = OrderedDict[]
Expand Down
6 changes: 3 additions & 3 deletions src/namedarraytypes.jl
Expand Up @@ -39,14 +39,14 @@ function checkdict(dict::Associative)
return OrderedDict{union, Int}(pairs)
end

mutable struct NamedArray{T,N,AT,DT} <: AbstractArray{T,N}
mutable struct NamedArray{T,N,AT} <: AbstractArray{T,N}
array::AT
dicts::DT
dicts::NTuple{N, OrderedDict}
dimnames::NTuple{N, Any}
function (::Type{S}){S<:NamedArray, T, N}(array::AbstractArray{T, N}, dicts::NTuple{N, OrderedDict}, dimnames::NTuple{N, Any})
size(array) == map(length, dicts) || error("Inconsistent dictionary sizes")
## dicts = map(dict -> checkdict(dict), dicts)
new{T, N, typeof(array), typeof(dicts)}(array, dicts, dimnames)
new{T, N, typeof(array)}(array, dicts, dimnames)
end
end

Expand Down
7 changes: 4 additions & 3 deletions src/names.jl
Expand Up @@ -31,19 +31,20 @@ strdimnames(n::NamedArray, d::Integer) = string(n.dimnames[d])


## seting names, dimnames
function setnames!{T,N,KT}(n::NamedArray{T,N}, v::Vector{KT}, d::Integer)
function setnames!(n::NamedArray{T,N}, v::Vector{KT}, d::Integer) where {T, N, KT}
returntype = typeof(n.dicts)
size(n.array, d) == length(v) || throw(DimensionMismatch("inconsistent vector length"))
keytype(n.dicts[d]) == KT || throw(TypeError(:setnames!, "second argument", keytype(n.dicts[d]), KT))
## n.dicts is a tuple, so we need to replace it as a whole...
vdicts = OrderedDict{Any,Int}[]
vdicts = []
for i = 1:length(n.dicts)
if i==d
push!(vdicts, OrderedDict(zip(v, 1:length(v))))
else
push!(vdicts, n.dicts[i])
end
end
n.dicts = tuple(vdicts...)::NTuple{N}
n.dicts = tuple(vdicts...)::returntype
end

function setnames!(n::NamedArray, v, d::Integer, i::Integer)
Expand Down
4 changes: 2 additions & 2 deletions test/constructors.jl
Expand Up @@ -27,8 +27,8 @@ n1 = @inferred NamedArray(Complex64, 5, 8)
n2 = @inferred NamedArray(a, (["s", "t"],[:a, :b, :c]), ("string", :symbol))

n = @inferred NamedArray(rand(2,4))
@inferred setnames!(n, ["one", "two"], 1)
@inferred setnames!(n, ["a", "b", "c", "d"], 2)
setnames!(n, ["one", "two"], 1)
setnames!(n, ["a", "b", "c", "d"], 2)

a = [1 2 3; 4 5 6]
n3 = @inferred NamedArray(a, (["a","b"],["C","D","E"]))
Expand Down
4 changes: 2 additions & 2 deletions test/init-namedarrays.jl
Expand Up @@ -2,8 +2,8 @@ n = @inferred NamedArray(rand(2,4))
Letters = [string(Char(64+i)) for i in 1:26]
letters = [string(Char(64+32+i)) for i in 1:26]

@inferred setnames!(n, ["one", "two"], 1)
@inferred setnames!(n, letters[1:4], 2)
setnames!(n, ["one", "two"], 1)
setnames!(n, letters[1:4], 2)

v = @inferred NamedArray(rand(1:100, 6), (letters[1:6],), (:index,))

Expand Down
4 changes: 2 additions & 2 deletions test/names.jl
Expand Up @@ -12,9 +12,9 @@ include("init-namedarrays.jl")
dn1 = ["", ""]
dn2 = ["", "", "", ""]

@inferred setnames!(n, dn1, 1)
setnames!(n, dn1, 1)
for (i, zh) in enumerate(dn2)
@inferred setnames!(n, zh, 2, i)
setnames!(n, zh, 2, i)
end

@test names(n) == Array[dn1, dn2]
Expand Down

0 comments on commit 85af84c

Please sign in to comment.