Composing types with non-concrete fields

Consider the MWE

struct Foo
    x::Any    # NOT CONCRETE
end

struct Bar{Ty, Tz}
    y::Ty
    z::Tz     # but fully parametrized here
end

f(b::Bar) = b.y + 1 # this function only uses the concrete field

b = Bar(1, Foo(9.0))

@code_warntype f(b) # I get no warnings on v0.6.2

which composes a type Foo with an abstract field (ie violating the performance recommendation) into Bar.

Questions:

  1. if I then use only the concrete fields of Bar, do I still get the performance benefits? (ie avoid the performance penalties?)
  2. is there a constraint, eg the type with abstract fields being the last field?
2 Likes

Any use of concrete fields should be fully optimizable no matter what is in the other fields.

julia> struct F
       a::Int
       b
       c
       d
       e
       end

julia> b = F(1,2,3,4,5)
F(1, 2, 3, 4, 5)

julia> f(A::F, B::F) = A.a + B.a
f (generic function with 1 method)

julia> @code_native f(b,b)
        .section        __TEXT,__text,regular,pure_instructions
; Function f {
; Location: REPL[33]:1
; Function +; {
; Location: REPL[33]:1
        movq    (%rsi), %rax
        addq    (%rdi), %rax
;}
        retq
        nopw    (%rax,%rax)
;}
3 Likes