These are chat archives for SimonDanisch/FixedSizeArrays.jl

2nd
Jun 2015
Kristoffer Carlsson
@KristofferC
Jun 02 2015 12:26
There is an interesting performance difference in accessing fields by name and by index:
This message was deleted
This message was deleted
Kristoffer Carlsson
@KristofferC
Jun 02 2015 12:35
Hm, I realized my benchmarks wasn't very good, have to recheck some stuff
Kristoffer Carlsson
@KristofferC
Jun 02 2015 13:14
Ok, some better benching now:
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
Kristoffer Carlsson
@KristofferC
Jun 02 2015 13:26
It looks like getindex for FSA's is not completely type stable
Simon
@SimonDanisch
Jun 02 2015 13:34
hmmm weird... indexing was usually ~ 3 times faster than indexing an array
Kristoffer Carlsson
@KristofferC
Jun 02 2015 13:34
Yeah, as I said, this must be something new because I would have noticed a performance bottle neck like this earlier in my usage
Simon
@SimonDanisch
Jun 02 2015 13:36
hmm.. maybe this is easily fixed by changing getindex to getindex(x, i) = x.(i)::eltype(x)
Kristoffer Carlsson
@KristofferC
Jun 02 2015 13:37
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
schlady
@schlady
Jun 02 2015 13:38
if I use an iterator it can inference the type of x
Kristoffer Carlsson
@KristofferC
Jun 02 2015 13:51
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.
schlady
@schlady
Jun 02 2015 14:12
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?
Simon
@SimonDanisch
Jun 02 2015 14:19
thats how its currently done :(
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
Kristoffer Carlsson
@KristofferC
Jun 02 2015 14:31
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
This message was deleted
schlady
@schlady
Jun 02 2015 14:36
if i print typeof(SZ) I get DataType
Kristoffer Carlsson
@KristofferC
Jun 02 2015 14:36
It is a Tuple{5}
schlady
@schlady
Jun 02 2015 14:36
I thought SZ is a Tuple instance
Kristoffer Carlsson
@KristofferC
Jun 02 2015 14:37
There is a difference now between Tuples that hold values and TupleTypes
schlady
@schlady
Jun 02 2015 14:45
Ah ok, got it :)
Kristoffer Carlsson
@KristofferC
Jun 02 2015 14:46
I think the problem is that a SZ.parameters is just a ::SimpleVectorand 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
schlady
@schlady
Jun 02 2015 14:50
SZ can't be a TupleType? Tuple{Int64,...}
Kristoffer Carlsson
@KristofferC
Jun 02 2015 14:52
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