# Performance of a type-unstable accumulator

**URL:** <https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169>\
**Category:** General Usage\
**Tags:** performance\
**Created:** [July 9, 2019, 2:18am UTC](https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169 "2019-07-09T02:18:55Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [July 9, 2019, 2:18am UTC](https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169/1 "2019-07-09T02:18:55Z")

</div>

One of the general performance tips is to ensure that an accumulator has the same type as the data that you’re accumulating using the `zero` function. Apparently, there’s no visible effect in my performance tests below.

Has Julia gotten better with optimization, or is it a case that’s too trivial to bring up the issue? I’m using Julia v1.1.1 on Mac.

```julia
julia> random_floats = rand(Float64, 100000);

julia> function double_sum(data)
           total = 0
           for v in data
               total += 2 * v
           end
           return total
       end;

julia> @btime double_sum($random_floats);
  103.515 μs (0 allocations: 0 bytes)

julia> function double_sum(data)
           total = zero(eltype(data))
           for v in data
               total += 2 * v
           end
           return total
       end;

julia> @btime double_sum($random_floats);
  103.505 μs (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [July 9, 2019, 2:25am UTC](https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169/2 "2019-07-09T02:25:01Z")

</div>

Yes, the compiler is pretty good at this these days.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [July 9, 2019, 2:31am UTC](https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169/3 "2019-07-09T02:31:38Z")

</div>

```julia
random_floats = rand(Float64, 100000);

function double_sum(data)
   total::Float32 = 0
   for v in data
       total += 2 * v
   end
   return total
end;

@btime double_sum($random_floats);

function double_sum(data)
   total = zero(eltype(data))
   for v in data
       total += 2 * v
   end
   return total
end;

@btime double_sum($random_floats);

```

```julia
  360.057 μs (0 allocations: 0 bytes)
  120.063 μs (0 allocations: 0 bytes)

```

In the first function since you didn’t explicitly set a type for `total` I’m guessing the compiler looked at the code and made it a Float64 so the performance is the same. When you force total to be a Float32 you see the difference…

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [July 9, 2019, 2:44am UTC](https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169/4 "2019-07-09T02:44:50Z")

</div>

That’s interesting. Looks like it’s bad because every Float64 has to be converted to Float32 before adding to the total. The overhead of the conversion is big.

More interestingly, if I declare `total` as Float64 and pass an array of Float32, then it performs well again. I guess the conversion from Float32 to Float64 is much cheaper.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [July 9, 2019, 5:56am UTC](https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169/5 "2019-07-09T05:56:01Z")

</div>

See [Union-splitting: what it is, and why you should care](https://julialang.org/blog/2018/08/union-splitting)

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [July 10, 2019, 3:27am UTC](https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169/6 "2019-07-10T03:27:46Z")

</div>

Converting Float23 to Float64 is mostly just inserting some zero bits here and there. Converting from Float64 to Float32 require rounding and checking for overflow, etc.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [July 10, 2019, 3:28am UTC](https://discourse.julialang.org/t/performance-of-a-type-unstable-accumulator/26169/7 "2019-07-10T03:28:59Z")

</div>

> [@pixel27](#):
>
> I’m guessing the compiler looked at the code and made it a Float64 so the performance is the same

A couple of things to try to check that:

1. Call `double_sum` on an empty `Float64` vector, see what it returns.
2. Look at the LLVM code or machine code with `@code_llvm` and `@code_native`.
