Update a row of a matrix with random numbers

Viewed 64

Suppose I have a matrix

beta = ones(1000,1000)

and I want to update one of the rows of beta. Suppose I did

@btime randn!(view(beta,1,:))

I get 3.766 μs (3 allocations: 112 bytes)

However, if I did @btime beta[1,:] = randn(1000), I get 3.453 μs (2 allocations: 7.95 KiB).

Two questions

  1. Why is in-place update slower than creating a new array?
  2. What is the fastest way to update beta[1,:] with randomly drawn numbers? If beta = ones(10,10), it looks like I should use StaticArrays, but I'm not sure how to.
1 Answers

The random number generation takes the bulk of the time. randn is optimized to generate collections of Normal random variables. Specifically, generating a vector is about 2.5x faster than generating N single samples for vectors of length N ~ 200 (and more).

If this is the place you wish to optimize (beware premature optimization), then creating a buffer of random Normals of 1024 or so, and drawing from it before refreshing it, might be optimal.

In order to measure the speed ratio of the two methods I used the following code:

using BenchmarkTools

ratio(k) = ( @belapsed [randn() for i=1:$k]) / ( @belapsed randn($k) )

[ratio(k) for k in [1,2,4,8,16,32,64,128,256,512,1024,2048,4096]]

Giving the following ratios:

13-element Vector{Float64}:
 1.0188417161077299
 1.0517378917378917
 1.0201505957529582
 0.8502604933018909
 1.2023468426000639
 1.664313080265282
 2.172084771444596
 3.259981975486662
 2.349527479585283
 3.0571514578137093
 2.670449479187776
 2.9401818181818187
 3.127237912876974

It can be seen from these values, that around 100, the ratio saturates at ~2.5x as previously suggested.

Related