These are chat archives for **SimonDanisch/FixedSizeArrays.jl**

This is hopefully turning into a good FixedSizeArray implementation. So far its a chaotic test bed.

There is an interesting performance difference in accessing fields by name and by index:

Hm, I realized my benchmarks wasn't very good, have to recheck some stuff

```
using GeometryTypes
v = Vector3{Int}(0,0,0)
v2 = [0, 0, 0]
function f(v, n)
x = 0
for i = 1:n
for row in 1:length(v)
x += v[row]
end
end
return x
end
@time f(v, 1_000_000)
# 518.823 milliseconds (3000 k allocations: 78125 KB, 3.03% gc time)
@time f(v2, 1_000_000)
# 1.020 milliseconds (4 allocations: 144 bytes)
```

using @code_warntype:

```
julia> @code_warntype f(v, 1_000_000)
Variables:
v::GeometryTypes.Vector3{Int64}
n::Int64
x::Any
#s571::Int64
i::Int64
#s572::Any
row::Any
```

But for the normal vector:

```
julia> @code_warntype f(v2, 1_000_000)
Variables:
v::Array{Int64,1}
n::Int64
x::Int64
#s571::Int64
i::Int64
#s572::Bool
row::Int64
```

I think this is something new... because I noticed a dramatic bottleneck in my code now that looped over a FSA and I don't recall seeing it before

It looks like getindex for FSA's is not completely type stable

hmmm weird... indexing was usually ~ 3 times faster than indexing an array

Yeah, as I said, this must be something new because I would have noticed a performance bottle neck like this earlier in my usage

hmm.. maybe this is easily fixed by changing getindex to getindex(x, i) = x.(i)::eltype(x)

length also seem to be unstable

```
julia> @code_warntype length(v)
Variables:
A::GeometryTypes.Vector3{Int64}
Body:
begin # /home/kristoffer/.julia/v0.4/FixedSizeArrays/src/core.jl, line 26:
GenSym(0) = (top(getfield))(SZ,:parameters)::SimpleVector
return mapfoldl($(Expr(:new, :((top(getfield))(Base,:IdFun)::Type{Base.IdFun}))),$(Expr(:new, :((top(getfield))(Base,:MulFun)::Type{Base.MulFun}))),GenSym(0))::Any
end::Any
```

Yeah, doing

`for val in v`

means that `x`

can be inferenced, it however doesn't improve the performance because it still calls `getfield`

which seems to be the base problem.
Hm this SZ.parameters is strange. It is a SimpleVector which is the base of the new tuple type. But why you have to call SZ.parameters?

if nothing has changed in the implementation of tuples, the Tuple{...} type doesn't have the right functions defined, but Tuple.parameters gives you the underlying simplevec, which has them

```
function test{T,N,SZ}(A::FixedArray{T, N, SZ}, inds::Real...)
t = eltype(SZ)
a = (t...)
k = sub2ind(a, inds...)
A.(k)
end
julia> @code_warntype test(v, 1)
Variables:
A::GeometryTypes.Vector3{Int64}
inds::Tuple{Float64}
t::Int64
a::Tuple
k::Any
Body:
begin # none, line 2:
t = 3 # line 3:
a = (top(_apply))(call,top(tuple),t::Int64)::Tuple # line 4:
k = sub2ind(a::Tuple,(top(getfield))(inds::Tuple{Float64},1)::Float64)::Any # line 5:
return (top(getfield))(A::GeometryTypes.Vector3{Int64},k)::Int64
end::Int64
```

There is a difference now between Tuples that hold values and TupleTypes

I think the problem is that a SZ.parameters is just a

`::SimpleVector`

and if you try to splat it with `...`

it is impossible to know from the type what tuple you will get
So inference just sees it as a

`Tuple`

which causes it to fail on the return value from `sub2ind`

by the way, what I wrote in the code block above with

`t = eltype(SZ)`

has to be `t = SZ.parameters`

Else it fails for matrices