# Performance degradation after upgrading from 0.5.1 to 0.6.2 -- how to avoid memory allocation?

**URL:** <https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971>\
**Category:** Performance\
**Created:** [March 25, 2018, 8:17pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971 "2018-03-25T20:17:40Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![jinliangwei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jinliangwei/32/1929_2.png) [@jinliangwei](https://discourse.julialang.org/u/jinliangwei)\
**Post date:** [March 25, 2018, 8:17pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/1 "2018-03-25T20:17:40Z")

</div>

```julia
for rating in ratings
    x_idx = rating[1] + 1
    y_idx = rating[2] + 1
    rv = rating[3]

     W_row = W[:, x_idx]
     H_row = H[:, y_idx]
     pred = dot(W_row, H_row)
     diff = rv - pred
     W_grad = -2 * diff .* H_row
     H_grad = -2 * diff .* W_row
     W[:, x_idx] = W_row - step_size .* W_grad
     H[:, y_idx] = H_row - step_size .* H_grad
end

```

Above is a piece of code whose performance degrades by ~20x (from 1.2 seconds to 32 seconds for some particular input data) after I upgraded to Julia v0.6.2 from v0.5.1. Even with v0.5.1, it’s 3~4x slower than the same program written in C++.

In the above code, `ratings` is a Vector of tuples, `W` and `H` are 2-dimensional arrays of roughly 100 by 5000.

I am guessing that it’s memory allocation that caused the problem.

Julia v0.6.2:  
32.802334 seconds (148.08 M allocations: 11.332 GiB, 4.71% gc time)

Julia v0.5.1:  
1.263061 seconds (18.58 M allocations: 6.835 GB, 9.55% gc time)

Why does v0.6.2 allocate much more memory?

In my C++ code, I would have pre-allocated memory for variables like `W_row` `H_row` etc and reuse the same memory across iterations. How would I do the same thing in Julia?

Memory allocation profiling (v0.6.2):

> 0 for iteration = 1:num\_iterations  
> 0 for rating in ratings  
> 59192224 x\_idx = rating[1] + 1  
> 55158016 y\_idx = rating[2] + 1  
> 32006688 rv = rating[3]  
> -  
> 2298050581 W\_row = W[:, x\_idx]  
> 2291205792 H\_row = H[:, y\_idx]  
> 32236624 pred = dot(W\_row, H\_row)  
> 32006688 diff = rv - pred  
> 3971640698 W\_grad = -2 \* diff .\* H\_row  
> 3968829312 H\_grad = -2 \* diff .\* W\_row  
> 5795581993 W[:, x\_idx] = W\_row - step\_size .\* W\_grad  
> 5793210528 H[:, y\_idx] = H\_row - step\_size .\* H\_grad  
> - end

Memory allocation profiling (v0.5.1):

> 0 for iteration = 1:num\_iterations  
> 0 for rating in ratings  
> 59192224 x\_idx = rating[1] + 1  
> 55158016 y\_idx = rating[2] + 1  
> 32006688 rv = rating[3]  
> -  
> 1793490040 W\_row = W[:, x\_idx]  
> 1792374528 H\_row = H[:, y\_idx]  
> 32279345 pred = dot(W\_row, H\_row)  
> 32006688 diff = rv - pred  
> 1825048125 W\_grad = -2 \* diff .\* H\_row  
> 1824381216 H\_grad = -2 \* diff .\* W\_row  
> 3618250719 W[:, x\_idx] = W\_row - step\_size .\* W\_grad  
> 3616755744 H[:, y\_idx] = H\_row - step\_size .\* H\_grad  
> - end

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 25, 2018, 8:21pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/2 "2018-03-25T20:21:08Z")

</div>

Please provide a complete reproducible example. It’s going to be impossible to make any definite statements about performance without knowing exactly how you’ve set up your problem. For example, is this code inside a function? Are W and H globals? What are the element types? These are all critically important to understanding the performance of your code.

If you provide a block of code that can be run locally then it will be much easier to help figure out the performance issue.

---

<div class="post-metadata">

**Author:** ![jinliangwei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jinliangwei/32/1929_2.png) [@jinliangwei](https://discourse.julialang.org/u/jinliangwei)\
**Post date:** [March 25, 2018, 8:28pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/3 "2018-03-25T20:28:55Z")

</div>

Thanks for your quick reply!

Please find my full program here: [Pastiebin.com 5ab805f723ae3](https://www.pastiebin.com/5ab805f723ae3)

---

<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:** [March 25, 2018, 8:45pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/4 "2018-03-25T20:45:37Z")

</div>

That’s still missing the input data file?

---

<div class="post-metadata">

**Author:** ![jinliangwei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jinliangwei/32/1929_2.png) [@jinliangwei](https://discourse.julialang.org/u/jinliangwei)\
**Post date:** [March 25, 2018, 8:52pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/5 "2018-03-25T20:52:11Z")

</div>

Please download a sample input from here: [http://www.cs.cmu.edu/~jinlianw/data/ratings.csv](http://www.cs.cmu.edu/~jinlianw/data/ratings.csv) (11MB)

BTW, both versions of Julia were built from the source tarball.

---

<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:** [March 25, 2018, 9:06pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/6 "2018-03-25T21:06:06Z")

</div>

Ok, so

```julia
ratings = Array{Tuple{Integer, Integer, Real}}(0)

```

is not concretely typed and will have quite bad performance. Change to e.g. `Array{Tuple{Int, Int, Float64}}`.  
There were also some other places where you could use in place dot assignment more effecitvely and using `view`s.

[https://gist.github.com/KristofferC/91a4084b500c9f198b59af2486297b03](https://gist.github.com/KristofferC/91a4084b500c9f198b59af2486297b03) runs at 2 seconds per iteration for me while the original code ran at 55 seconds per iteration.

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [March 25, 2018, 9:06pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/7 "2018-03-25T21:06:56Z")

</div>

Is there any reason you cannot replace `Tuple{Integer, Integer, Real}` with `Tuple{Int, Int, Float64}`? The latter is going to be more more efficient. It could also be even faster to store the data as three vectors rather than as a vector of 3-tuples.

---

<div class="post-metadata">

**Author:** ![jinliangwei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jinliangwei/32/1929_2.png) [@jinliangwei](https://discourse.julialang.org/u/jinliangwei)\
**Post date:** [March 25, 2018, 10:08pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/8 "2018-03-25T22:08:33Z")

</div>

Great! Thanks! By changing the array type and using `views` I could reduce the runtime down to 0.63 seconds from 32 seconds, and further down to 0.59 seconds by using in-place dot assignment `.=`. However, `@.` causes exception – although I never saw it before I take it’s just another way of writing in place dot assignments?

---

<div class="post-metadata">

**Author:** ![jinliangwei](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jinliangwei/32/1929_2.png) [@jinliangwei](https://discourse.julialang.org/u/jinliangwei)\
**Post date:** [March 25, 2018, 10:09pm UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/9 "2018-03-25T22:09:06Z")

</div>

Thanks! Yes, fixing the tuple type did help!

---

<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:** [March 26, 2018, 9:33am UTC](https://discourse.julialang.org/t/performance-degradation-after-upgrading-from-0-5-1-to-0-6-2-how-to-avoid-memory-allocation/9971/10 "2018-03-26T09:33:05Z")

</div>

Yes `@.` is just a way of dotting all operators in the expression.
