# Very simple code, why would there be performance problems

**URL:** <https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848>\
**Category:** Performance\
**Tags:** question\
**Created:** [December 15, 2020, 3:33am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848 "2020-12-15T03:33:08Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zq\_F](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zq_f/32/20147_2.png) [@Zq\_F](https://discourse.julialang.org/u/Zq_F)\
**Post date:** [December 15, 2020, 3:33am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/1 "2020-12-15T03:33:08Z")

</div>

Hello, everyone  
Very simple code, the speed is really slow, I suspect that the method of using Ref in the structure is wrong  
Everyone, please take a look, thank you

```julia

mutable struct T3
  f1::Int64
  f2::String
  f3::Float64
  EvlP1::Ref{Float64}
  f5::Vector{Int64}
  function T3()
    this = new()
    this.EvlP1 = Ref{Float64}(3.0)
    return this
  end
end

function test() 
  t3=T3()
  #cc=0.1::Float64
  cc=Float64(0.1)
  for i = 1:10^8
    cc = cc +t3.EvlP1[]
  end
  println(cc)  
end

#@time test()
@code_warntype test()

```

The following is the result of code\_warntype, 3 places are red  
Variables  
#self#::Core.Compiler.Const(test, false)  
t3::T3  
cc::Any  
@\_4::Union{Nothing, Tuple{Int64,Int64}}  
i::Int64

Body::Nothing  
1 ── (t3 = Main.T3())  
││ (cc = Main.Float64(0.1))  
││ %3 = Core.apply\_type(Base.Val, 8)::Core.Compiler.Const(Val{8}, false)  
││ %4 = (%3)()::Core.Compiler.Const(Val{8}(), false)  
││ %5 = Base.literal\_pow(Main.:^, 10, %4)::Int64  
││ %6 = (1:%5)::Core.Compiler.PartialStruct(UnitRange{Int64}, Any[Core.Compiler.Const(1, false), Int64])  
││ (@\_4 = Base.iterate(%6))  
││ %8 = (@\_4 === nothing)::Bool  
││ %9 = Base.not\_int(%8)::Bool  
└└──── goto #4 if not %9  
2 ┄┄ %11 = @\_4::Tuple{Int64,Int64}::Tuple{Int64,Int64}  
││ (i = Core.getfield(%11, 1))  
││ %13 = Core.getfield(%11, 2)::Int64  
││ %14 = cc::Any \<--------------  
││ %15 = Base.getproperty(t3, :EvlP1)::Ref{Float64} \<--------------  
││ %16 = Base.getindex(%15)::Any \<--------------  
││ (cc = %14 + %16)  
││ (@\_4 = Base.iterate(%6, %13))  
││ %19 = (@\_4 === nothing)::Bool  
││ %20 = Base.not\_int(%19)::Bool  
└└──── goto #4 if not %20  
3 ── goto #2  
4 ┄┄ %23 = Main.println(cc)::Core.Compiler.Const(nothing, false)  
└└──── return %23

---

<div class="post-metadata">

**Author:** ![Zq\_F](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zq_f/32/20147_2.png) [@Zq\_F](https://discourse.julialang.org/u/Zq_F)\
**Post date:** [December 15, 2020, 3:39am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/2 "2020-12-15T03:39:09Z")

</div>

Very slow  
3.660509 seconds (200.00 M allocations: 2.980 GiB, 5.72% gc time)

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [December 15, 2020, 3:45am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/3 "2020-12-15T03:45:54Z")

</div>

Why are you using a `Ref` at all here?

---

<div class="post-metadata">

**Author:** ![xzackli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xzackli/32/38301_2.png) [@xzackli](https://discourse.julialang.org/u/xzackli)\
**Post date:** [December 15, 2020, 4:00am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/4 "2020-12-15T04:00:43Z")

</div>

Welcome! To echo Oscar’s complaint, you already have a mutable struct, so you don’t need the Ref here.

If you really want the behavior of a C pointer, replace `Ref` with `Base.RefValue{Float64}` to avoid using an abstract type.

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [December 15, 2020, 6:36am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/5 "2020-12-15T06:36:04Z")

</div>

Aside from what already said, `Ref` is an abstract type but, for `Number`s, it has a constructor and returns value with type `Base.RefValue`. However, if you use `Ref` as type then the value `boxed` and this causes performance degradation and allocations for each access.

---

<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:** [December 15, 2020, 7:45am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/6 "2020-12-15T07:45:12Z")

</div>

Hi @Zq_F,

it would also help to know, what you are up to?

---

<div class="post-metadata">

**Author:** ![Zq\_F](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zq_f/32/20147_2.png) [@Zq\_F](https://discourse.julialang.org/u/Zq_F)\
**Post date:** [December 15, 2020, 9:09am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/7 "2020-12-15T09:09:42Z")

</div>

Thank you everyone,  
it was resolved after changing to Base.RefValue{Float64}  
I am a beginner, ask what method to check if the type is abstract type

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 15, 2020, 12:24pm UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/8 "2020-12-15T12:24:59Z")

</div>

There is `isconcretetype`.

---

<div class="post-metadata">

**Author:** ![Zq\_F](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zq_f/32/20147_2.png) [@Zq\_F](https://discourse.julialang.org/u/Zq_F)\
**Post date:** [December 15, 2020, 2:04pm UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/9 "2020-12-15T14:04:16Z")

</div>

thank you very much

---

<div class="post-metadata">

**Author:** ![Ronneesley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronneesley/32/11072_2.png) [@Ronneesley](https://discourse.julialang.org/u/Ronneesley)\
**Post date:** [December 16, 2020, 4:32pm UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/10 "2020-12-16T16:32:23Z")

</div>

Why not?

```julia
mutable struct T3
  f1::Int64
  f2::String
  f3::Float64
  EvlP1::Float64
  f5::Vector{Int64}
  function T3()
    this = new()
    this.EvlP1 = 3.0
    return this
  end
end

function test() 
  t3 = T3()
  cc = 0.1
  for i = 1:10^8
    cc = cc + t3.EvlP1
  end
  println(cc)  
end

@time test()
3.000000001e8
  0.201632 seconds (468.36 k allocations: 21.575 MiB, 1.58% gc time)

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [December 16, 2020, 5:49pm UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/11 "2020-12-16T17:49:56Z")

</div>

> [@Ronneesley](#):
>
> ```julia
> @time test()
> 3.000000001e8
> 0.201632 seconds (468.36 k allocations: 21.575 MiB, 1.58% gc time)
> 
> ```

You should run it at least twice:

```julia
julia> @time test()
3.000000001e8
  0.221929 seconds (466.24 k allocations: 21.460 MiB)

julia> @time test()
3.000000001e8
  0.088707 seconds (9 allocations: 592 bytes)

```

---

<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:** [December 16, 2020, 8:05pm UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/12 "2020-12-16T20:05:20Z")

</div>

> [@DNF](#):
>
> You should run it at least twice:

Julia code gets compiled at runtime. So the first time you call a function you have compilation overhead. However, most of the time you are likely not interested in measuring this overhead. A good way to avoid this issue is to use the `BenchmarkTools` package to do your benchmarks, which automatically takes care that this does not happen.

> **[GitHub - JuliaCI/BenchmarkTools.jl: A benchmarking framework for the Julia...](https://github.com/JuliaCI/BenchmarkTools.jl)**
>
> A benchmarking framework for the Julia language. Contribute to JuliaCI/BenchmarkTools.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![Zq\_F](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zq_f/32/20147_2.png) [@Zq\_F](https://discourse.julialang.org/u/Zq_F)\
**Post date:** [December 21, 2020, 1:25am UTC](https://discourse.julialang.org/t/very-simple-code-why-would-there-be-performance-problems/51848/13 "2020-12-21T01:25:21Z")

</div>

Thank you all, the problem has been solved
