fill_W1! allocates memory because it makes copies when constructing the 
right hand sides. fill_W2 allocates memory in order to construct the 
comprehensions (that you then discard). In both cases memory allocation 
could plausibly be avoided by a sufficiently smart compiler, but until 
Julia becomes that smart, have a look at the sub function to provide views 
instead of copies for the right hand sides of fill_W1!.

On Thursday, July 21, 2016 at 5:07:34 PM UTC+2, Michael Prange wrote:
>
> I'm a new user, so have mercy in your responses. 
>
> I've written a method that takes a matrix and vector as input and then 
> fills in column icol of that matrix with the vector of given values that 
> have been shifted upward by ishift indices with periodic boundary 
> conditions. To make this clear, given the matrix
>
> W = [1  2
>         3  4
>         5  6]
>
> the vector w = [7  8  9], icol = 2 and ishift = 1, the new value of W is 
> given by
>
> W = [1  8
>         3  9
>         5  7]
>
> I need a fast way of doing this for large matrices. I wrote three methods 
> that should (In my naive mind) give the same performance results, but @time 
> reports otherwise.  The method definitions and the performance results are 
> given below. Can someone teach me why the results are so different? The 
> method fill_W! is too wordy for my tastes, but the more compact notation in 
> fill_W1! and fill_W2! achieve poorer results. Any why do these latter two 
> methods allocate so much memory when the whole point of these methods is to 
> use already-allocated memory.
>
> Michael
>
> ### Definitions
>
>
> function fill_W1!{TF}(W::Matrix{TF}, icol::Int, w::Vector{TF}, 
>     ishift::Int)
>     @assert(size(W,1) == length(w), "Dimension mismatch between W and w")
>     W[1:(end-ishift),icol] = w[(ishift+1):end]
>     W[(end-(ishift-1)):end,icol] = w[1:ishift]
>     return
> end
>
>
> function fill_W2!{TF}(W::Matrix{TF}, icol::Int, w::Vector{TF}, 
>     ishift::Int)
>     @assert(size(W,1) == length(w), "Dimension mismatch between W and w")
>     [W[i,icol] = w[i+ishift] for i in 1:(length(w)-ishift)]
>     [W[end-ishift+i,icol] = w[i] for i in 1:ishift]
>     return
> end
>
>
> function fill_W!{TF}(W::Matrix{TF}, icol::Int, w::Vector{TF}, 
>     ishift::Int)
>     @assert(size(W,1) == length(w), "Dimension mismatch between W and w")
>     n = length(w)
>     for j in 1:(n-ishift)
>         W[j,icol] = w[j+ishift]
>     end
>     for j in (n-(ishift-1)):n
>         W[j,icol] = w[j-(n-ishift)]
>     end
> end
>
>
> # Performance Results
> julia>
> W = rand(1000000,2)
> w = rand(1000000)
> println("fill_W!:")
> println(@time fill_W!(W, 2, w, 2))
> println("fill_W1!:")
> println(@time fill_W1!(W, 2, w, 2))
> println("fill_W2!:")
> println(@time fill_W2!(W, 2, w, 2))
>
>
> Out>
> fill_W!:
>  0.002801 seconds (4 allocations: 160 bytes)
> nothing
> fill_W1!:
>  0.007427 seconds (9 allocations: 7.630 MB)
> [0.152463397611579,0.6314166578356002]
> fill_W2!:
>  0.005587 seconds (7 allocations: 7.630 MB)
> [0.152463397611579,0.6314166578356002]
>
>
>

Reply via email to