# Raytracing weekend: debugging unexpected allocations

**URL:** https://discourse.julialang.org/t/raytracing-weekend-debugging-unexpected-allocations/83196
**Category:** New to Julia
**Tags:** performance
**Created:** [June 22, 2022, 6:07pm UTC](https://discourse.julialang.org/t/raytracing-weekend-debugging-unexpected-allocations/83196 "2022-06-22T18:07:27Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![mikegedelman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikegedelman/32/37366_2.png) [@mikegedelman](https://discourse.julialang.org/u/mikegedelman)
#### Post date: [June 22, 2022, 6:07pm UTC](https://discourse.julialang.org/t/raytracing-weekend-debugging-unexpected-allocations/83196/1 "2022-06-22T18:07:27Z")

</div>

Hello,

I’m new to Julia, and am out of ideas on how to prevent my code from allocating. I’ve made a fairly naive translation of the Raytracing Weekend program into Julia. I’m aware that I’m not the first person to do this, and when comparing my code to others’ it doesn’t seem that different, but it seems significantly slower. My code runs about 10x slower than the Rust implementation I wrote. I was hoping to get it much closer than that.

Here’s the function I’m trying to understand:

```julia
@inline function hit(sphere::Sphere, ray::Ray, tMin::Float64, tMax::Float64)::Union{HitRecord,Nothing}
    oc = ray.origin .- sphere.center
    a = lengthSquared(ray.direction)
    half_b = dot(oc, ray.direction)
    c = lengthSquared(oc) - (sphere.radius * sphere.radius)
    discriminant = (half_b * half_b) - (a * c)

    if discriminant < 0
        return nothing
    end

    sqrtd = sqrt(discriminant)
    root = (-half_b - sqrtd) / a
    if root < tMin || tMax < root
        root = (-half_b + sqrtd) / a

        if root < tMin || tMax < root
            return nothing
        end
    end

    t = root
    p = at(ray, root)
    outwardNormal = (p .- sphere.center) ./ sphere.radius
    frontFace, normal = getFaceNormal(ray, outwardNormal)
    HitRecord(p, normal, t, frontFace, sphere.material)
end

```

[Here’s a link to the full code on github if you want to see more context.](https://github.com/mikegedelman/raytracing-weekend-julia/blob/main/src/hit.jl#L64)

The very last line that creates a HitRecord is allocating. (Determined by running with `--track-allocation=user`.) I’ve tried a variety of things, including making Sphere generic over Material, and adding tons of extra type annotations, with no luck.

Most specifically, I’m trying to understand why there’s an allocation in this function where I’m returning an immutable struct. I’m guessing it still has something to do with how I’m storing `material`, but in [this thread](https://discourse.julialang.org/t/ray-tracing-in-a-week-end-julia-vs-simd-optimized-c/72958) about optimizing the raytracing weekend code, the code’s structs are very similar, storing an abstract `Material` type on the `HitRecord`.

---

<div class="post-metadata">

### Author: ![moeddel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moeddel/32/18641_2.png) [@moeddel](https://discourse.julialang.org/u/moeddel)
#### Post date: [June 22, 2022, 6:42pm UTC](https://discourse.julialang.org/t/raytracing-weekend-debugging-unexpected-allocations/83196/2 "2022-06-22T18:42:08Z")

</div>

How do you represent 3D coordinates? as `Vector`?

In this case you can gain a lot by using `SVector` provided by the package `StaticArrays`. Statically sized means that the size can be determined from the _type_, which allows the compiler to make more aggressive optimizations.

---

<div class="post-metadata">

### Author: ![mikegedelman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikegedelman/32/37366_2.png) [@mikegedelman](https://discourse.julialang.org/u/mikegedelman)
#### Post date: [June 22, 2022, 6:46pm UTC](https://discourse.julialang.org/t/raytracing-weekend-debugging-unexpected-allocations/83196/3 "2022-06-22T18:46:02Z")

</div>

Thanks! Yes, I’m using `StaticArrays`:

```julia
const Vec3 = SVector{3,Float64}

```

> <https://github.com/mikegedelman/raytracing-weekend-julia/blob/main/src/vec3.jl#L4>

---

<div class="post-metadata">

### Author: ![paulmelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmelis/32/35063_2.png) [@paulmelis](https://discourse.julialang.org/u/paulmelis)
#### Post date: [June 22, 2022, 6:58pm UTC](https://discourse.julialang.org/t/raytracing-weekend-debugging-unexpected-allocations/83196/4 "2022-06-22T18:58:17Z")

</div>

> [@mikegedelman](#):
>
> Most specifically, I’m trying to understand why there’s an allocation in this function where I’m returning an immutable struct. I’m guessing it still has something to do with how I’m storing `material`, but in [this thread](https://discourse.julialang.org/t/ray-tracing-in-a-week-end-julia-vs-simd-optimized-c/72958) about optimizing the raytracing weekend code, the code’s structs are very similar, storing an abstract `Material` type on the `HitRecord`.

I _think_ that the issue is that in your `HitRecord` the `material` field is of abstract type `Material`, which will cause an allocation. In my own version ([here](https://github.com/paulmelis/riow.jl/blob/main/src/material.jl)) I use a union: `const Material = Union{Lambertian, Metal, Dielectric}`.
