# Unexpected Allocations in Julia 0.5

**URL:** <https://discourse.julialang.org/t/unexpected-allocations-in-julia-0-5/723>\
**Category:** General Usage\
**Created:** [December 4, 2016, 2:17pm UTC](https://discourse.julialang.org/t/unexpected-allocations-in-julia-0-5/723 "2016-12-04T14:17:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![michakraus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michakraus/32/222105_2.png) [@michakraus](https://discourse.julialang.org/u/michakraus)\
**Post date:** [December 4, 2016, 2:17pm UTC](https://discourse.julialang.org/t/unexpected-allocations-in-julia-0-5/723/1 "2016-12-04T14:17:51Z")

</div>

I am working on an ODE/DAE solver in Julia ([GitHub - JuliaGNI/GeometricIntegrators.jl: Geometric Numerical Integration in Julia](https://github.com/DDMGNI/GeomDAE.jl)), where I encountered a problem with unexpected allocations when calling a function which is part of a type, e.g.,

```julia
type Data{T}
    t::T # time t
    x::Vector{T} # solution x
    y::Vector{T} # vector field y=f(t,x)
    f::Function # function f
end

```

called by

```julia
function f(t, x, fx)
    fx[1] = x[2]
    fx[2] = sin(x[1])
    nothing
end

t = 1.
x = [1., 2.]
y = zeros(x) 
d = Data(t, x, y, f)

@time d.f(d.t, d.x, d.y)

```

which (after warmup) leads to

```julia
  0.000002 seconds (1 allocation: 16 bytes)

```

The problem is the t parameter. If fixed, e.g.,

```julia
@time d.f(1., d.x, d.y)

```

the allocation disappears and the result becomes

```julia
  0.000001 seconds

```

Similarly, if the t parameter is removed altogether or wrapped into an array, the allocation disappears as well, e.g.,

```julia
function f(x, fx)
    fx[1] = x[2]
    fx[2] = sin(x[1])
    nothing
end

type Data{T}
    t::T # time t
    x::Vector{T} # solution x
    y::Vector{T} # vector field y=f(t,x)
    f::Function # function f
end

t = 1.
x = [1., 2.]
y = zeros(x) 
d = Data(t, x, y, f)

@time d.f(d.x, d.y)

```

which leads to

```julia
  0.000000 seconds

```

or

```julia
function f(t, x, fx)
    fx[1] = x[2]
    fx[2] = sin(x[1])
    nothing
end

type Data{T}
    t::Vector{T}
    x::Vector{T}
    y::Vector{T}
    f::Function
end

t = [1.]
x = [1., 2.]
y = zeros(x) 
d = Data(t, x, y, f)

@time d.f(d.t, d.x, d.y)

```

which leads to

```julia
  0.000001 seconds

```

So Julia seems to have troubles figuring out the type of the scalar. This problem persists even if I fix the type in the function header, i.e.,

```julia
function f{T}(t::T, x::Vector{T}, y::Vector{T})
   ...
end

```

or

```julia
function f(t::Float64, x::Vector{Float64}, y::Vector{Float64})
   ...
end

```

Below is the full “minimal” example,

```julia
# define function to integrate
function f(t, x, fx)
    fx[1] = x[2]
    fx[2] = sin(x[1])
    nothing
end

# define datatype which holds time t, solution x,
# vector field y=f(t,x), and function f
type Data{T}
    t::T
    x::Vector{T}
    y::Vector{T}
    f::Function
end

# function for timing f with data from data type
function call_f(d::Data)
    d.f(d.t, d.x, d.y)
    
    @time d.f(d.t, d.x, d.y)
    @time d.f(1.0, d.x, d.y)
end

# create data type and call f with wrapped data
function time_f1()
    t = 1.
    x = [1., 2.]
    y = zeros(x) 
    my_data = Data(t, x, y, f)
    call_f(my_data)
end

# function for timing f without wrapping data
function time_f2()
    t = 1.
    x = [1., 2.]
    y = zeros(x)

    f(t, x, y)
    
    @time f(t, x, y)
    @time f(1., x, y)
end

# time f, calling it with and without data type
time_f1()
time_f2()

```

Calling this script leads to

```julia
  0.000002 seconds (1 allocation: 16 bytes)
  0.000001 seconds
  0.000000 seconds
  0.000000 seconds

```

---

<div class="post-metadata">

**Author:** ![gragusa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gragusa/32/3547_2.png) [@gragusa](https://discourse.julialang.org/u/gragusa)\
**Post date:** [December 4, 2016, 2:56pm UTC](https://discourse.julialang.org/t/unexpected-allocations-in-julia-0-5/723/2 "2016-12-04T14:56:27Z")

</div>

What happens if you

```julia
const t = 1.

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 4, 2016, 3:20pm UTC](https://discourse.julialang.org/t/unexpected-allocations-in-julia-0-5/723/3 "2016-12-04T15:20:08Z")

</div>

`const` will not work in local scope.

Your issue is not from `t` but `f`. The call on `d.f` cannot be inferred so it’s a dynamic dispatch. `t` needs to be boxed as a result of that. Allocation is only needed if it was not boxed already.

If you want to optimize for performance, you should remove the dynamic dispatch which should remove the allocation too although the allocation you see should not cause any noticeable performance issue.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [December 4, 2016, 4:46pm UTC](https://discourse.julialang.org/t/unexpected-allocations-in-julia-0-5/723/4 "2016-12-04T16:46:45Z")

</div>

> [@michakraus](#):
>
> type Data{T}  
> t::T # time t  
> x::Vector{T} # solution x  
> y::Vector{T} # vector field y=f(t,x)  
> f::Function # function f  
> end

Instead:

```julia
type Data{T,F}
    t::T # time t
    x::Vector{T} # solution x
    y::Vector{T} # vector field y=f(t,x)
    f::F # function f
end

```

Each function has its own type, thus to make the field concrete, you need to give it a type parameter.

---

<div class="post-metadata">

**Author:** ![michakraus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michakraus/32/222105_2.png) [@michakraus](https://discourse.julialang.org/u/michakraus)\
**Post date:** [December 5, 2016, 2:28am UTC](https://discourse.julialang.org/t/unexpected-allocations-in-julia-0-5/723/5 "2016-12-05T02:28:41Z")

</div>

@yuyichao, @mauro3  
Thanks for making this clear. Now I see the problem. @mauro3’s fix solved the issue. Regarding performance, for simple functions like in my example, the difference is usually about a factor of ~1.5, but can be up to ~2. For more complicated functions I expect it to be smaller, though.
