I think this is down to Julia avoiding specialisation on the `ykey` type in
`reshape`, which sometime happens if it's (heuristically) determined that
doing so will prevent large amounts of unnecessary code being generated.
You can always force specialisation with a type parameter:

reshape{T}(xs, ys, ykey::Type{Val{T}}) = begin

However, this is unnecessary if you make the types simpler. Changing
`::Type{Val{T}}` to `::Val{T}` and `Val{T}` to `Val{(1,3)}()` will do the
trick if you want to stick with that approach, but just use a tuple
directly:

@generated construct(key::Tuple, value) = begin
  :(begin
      $(Expr(:meta, :inline))
      tuple($([:(value[key[$i]]) for i in 1:length(key.parameters)]...))
    end)
end

reshape(xs, ys, ykey) = begin
  for x in xs
    push!(ys, construct(ykey, x))
  end
  return ys
end

reshape([(10,11,12),(13,14,15)],NTuple{2,Int}[],(1,3))

Above: 0.021351 seconds (500.00 k allocations: 30.518 MB, 17.76% gc time)
Type{Val{T}} reshape2: 0.021599 seconds (500.00 k allocations: 30.518 MB,
19.60% gc time)


On Tue, 29 Dec 2015 at 07:16 Jamie Brandon <[email protected]> wrote:

> I have two versions of this reshape function -
> https://gist.github.com/jamii/62b3c3695fba95f3f09b
>
> The produce near-identical ast from code_warntype -
> https://www.diffchecker.com/awnv9zvv
>
> But code_lowered shows that reshape naively boxes tuples whereas reshape2
> does something much more complicated -
> https://www.diffchecker.com/jb6aurpl
>
> The result is that reshape2 is much faster:
>
> reshape: 0.316513 seconds (2.00 M allocations: 95.036 MB, 5.41% gc time)
> reshape2:  0.218963 seconds (41 allocations: 34.001 MB, 0.85% gc time)
>
> What's going on? How can I make reshape avoid boxing?
>

Reply via email to