# How to access shared "inherited" fields without paying multiple dispatch performance price?

**URL:** <https://discourse.julialang.org/t/how-to-access-shared-inherited-fields-without-paying-multiple-dispatch-performance-price/26762>\
**Category:** Performance\
**Tags:** inheritance\
**Created:** [July 24, 2019, 11:43pm UTC](https://discourse.julialang.org/t/how-to-access-shared-inherited-fields-without-paying-multiple-dispatch-performance-price/26762 "2019-07-24T23:43:52Z")\
**Posts on this page:** 1\
**Showing post:** 12

<div class="post-metadata">

**Author:** ![Russ](https://avatars.discourse-cdn.com/v4/letter/r/e36b37/32.png) [@Russ](https://discourse.julialang.org/u/Russ)\
**Post date:** [July 25, 2019, 7:42am UTC](https://discourse.julialang.org/t/how-to-access-shared-inherited-fields-without-paying-multiple-dispatch-performance-price/26762/12 "2019-07-25T07:42:07Z")

</div>

Ok, I just couldn’t leave this one alone. It **is** possible to read the the “shared” fields with no overhead, but it’s super unsafe. I used `unsafe_load` along with a modified version of `pointer_from_objref` that doesn’t check if classes are mutable or not (that check is really slow). I also made all the structs mutable, because they obviously need to be heap allocated for my use case (still learning! 😁).

The performance is much better:

```julia
julia> @time speedTest()
10003000000
  0.082848 seconds (10.03 k allocations: 413.281 KiB)

```

That’s ~30x faster than the fastest method dispatch. Obviously this is totally a microbenchmark and does not represent real-world usage. Still, it does show the overhead was there, and it’s gone now. The higher count of allocations is from heap allocating the structs.

I benchmarked a C++ translation of this code, at it runs at the same speed as Julia. I’m honestly very impressed with Julia here – what I’m doing is totally against the design of the language, but Julia gives me the tools to do it anyway and compiles it down into a super-optimized result. And then I can write a macro to wrap it all up into something that looks nice. Awesome.

The code is below. This is just a quick proof-of-concept and very unsafe. `getLength()` is pulling from pointer offset 1 in the struct, you could get the offsets of the other fields with `fieldoffset()`. Also, for struct references (pointers) you’d need to convert them back to objrefs.

```julia
abstract type Car end

mutable struct HondaAccord <: Car
    length::Int64
end

mutable struct ToyotaCamry1 <: Car
    length::Int64
end

mutable struct ToyotaCamry2 <: Car
    length::Int64
end

function unsafe_pointer_from_objref(@nospecialize(x))
    ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), x)
end

function getLength(a::Car)::Int64
    unsafe_load(Core.Intrinsics.bitcast(Ptr{Int64}, unsafe_pointer_from_objref(a)), 1)
end

function speedTest()
    cars = Car[]
    while length(cars) < 10000
        push!(cars, HondaAccord(100))
        push!(cars, ToyotaCamry1(100))
        push!(cars, ToyotaCamry2(100))
    end

    sum = 0::Int64
    for j = 1:10000
        for i = 1:length(cars)
            sum = sum + getLength(cars[i])
        end
    end

    println(sum)
end

```

---

_[View the full topic](https://discourse.julialang.org/t/how-to-access-shared-inherited-fields-without-paying-multiple-dispatch-performance-price/26762)._
