The biggest problem seems to be the main loop in calc_net.jl:

for idx = 1:numO

    o = o_vec[idx]

    # conditions in which something occurs
    cond_A_su = (o .< b_hist[:,3]) & (b_hist[:,1] .== 65)
    cond_B_su = (o .> b_hist[:,3]) & (b_hist[:,1] .== 66)

    # conditions in which something occurs
    cond_A_pu = (o .== b_hist[:,3]) & (b_hist[:,1] .== 65)
    cond_B_pu = (o .== b_hist[:,3]) & (b_hist[:,1] .== 66)

    # sum stuff according to conditions
    b_A_su_[idx] = sum(b_hist_col2 .* cond_A_su)
    b_B_su_[idx] = sum(b_hist_col2 .* cond_B_su)

    # sum stuff according to conditions
    b_A_pu_[idx] = sum(b_hist_col2 .* cond_A_pu)
    b_B_pu_[idx] = sum(b_hist_col2 .* cond_B_pu)

end # idx


Every single instance of  .* , .== and .> creates a new for-loop in the 
machine code produced by Julia and each one requires the creation of a new 
temporary variable. In Matlab this is a necessary evil because native 
Matlab loops are so slow. But Julia loops are fast, so you should write 
this code the way you would write it in C or Fortran:

    # sum stuff according to conditions
    b_A_su_[idx] = 0
    b_B_su_[idx] = 0

    # sum stuff according to conditions
    b_A_pu_[idx] = 0
    b_B_pu_[idx] = 0
    for j in 1:length(b_hist[:,3])
        # conditions in which something occurs
        cond_A_su = (o < b_hist[j,3]) & (b_hist[j,1] .== 65)
        cond_B_su = (o > b_hist[j,3]) & (b_hist[j,1] .== 66)

        # conditions in which something occurs
        cond_A_pu = (o == b_hist[j,3]) & (b_hist[j,1] .== 65)
        cond_B_pu = (o == b_hist[j,3]) & (b_hist[j,1] .== 66)

        # sum stuff according to conditions
        b_A_su_[idx] += b_hist_col2[j] * cond_A_su
        b_B_su_[idx] += b_hist_col2[j] * cond_B_su

        # sum stuff according to conditions
        b_A_pu_[idx] += b_hist_col2[j] * cond_A_pu
        b_B_pu_[idx] += b_hist_col2[j] * cond_B_pu
    end


On my computer, this change reduces the execution time and memory 
allocation (both) by a factor of 3. So this change alone does not make the 
program fast, but I think it is illustrative of the type of changes that 
are needed. Another place I would look at is:

  # retrieve some history
  b_hist = reshape(sim["b"][d, 1:t, i, :], t, 3)
  b_hist_col2 = reshape(sim["b"][d, 1:t, i, 2], t, 1)
  b_hist_col2_A = b_hist_col2 .* (b_hist[:,1] .== 65)
  b_hist_col2_B = b_hist_col2 .* (b_hist[:,1] .== 66)


The first two lines require memory allocation and might also have a bad 
memory profile. I can't rewrite it because I'm not sure what the program is 
supposed to do. The last two lines are another set of for-loops that could 
be bundled together like I showed you.

In general, I think you can improve the code by switching to for-loops (as 
you would in C or C++) and memory allocation.

Cheers,
Daniel.



On Saturday, 19 September 2015 19:50:50 UTC+2, Adam wrote:
>
> Hi, I'm a novice to Julia but have heard promising things and wanted to 
> see if the language can help with a problem I'm working on. I have some 
> Matlab code with some user-defined functions that runs a simulation in 
> about ~1.4 seconds in Matlab (for a certain set of parameters that 
> characterize a small problem instance). I translated the code into Julia, 
> and to my surprise the Julia code runs 5x to 30x slower than the Matlab 
> code. I'll be running this code on much larger problem instances many, many 
> times (within some other loops), so performance is important here. 
>
> I created a GitHub gist that contains a stripped-down version of the Julia 
> code that gets as close to (as I can find) the culprit of the problem. The 
> gist is here: https://gist.github.com/anonymous/010bcbda091381b0de9e. A 
> quick description: 
>
>    - set_up.jl sets up parameters and other items.
>    - set_up_sim.jl sets up items particular to the simulation.
>    - simulation.jl runs the simulation.
>    - calc_net.jl, dist_o_i.jl, and update_w.jl are user-defined functions 
>    executed in the simulation. 
>
>
> On my laptop (running in Juno with Julia version 0.3.10), this code yields:
> elapsed time: 43.269609577 seconds (20297989440 bytes allocated, 38.77% gc 
> time)
> elapsed time: 38.500054653 seconds (20291872804 bytes allocated, 40.41% gc 
> time)
> elapsed time: 40.238907235 seconds (20291869252 bytes allocated, 39.44% gc 
> time)
>
> Why is so much memory used, and why is so much time spent in garbage 
> collection?
>
> I'm familiar with 
> http://docs.julialang.org/en/release-0.3/manual/performance-tips/ and 
> have tried to follow these tips to the best of my knowledge. One example of 
> what might be seen as low-hanging fruit: I tried removing the type 
> declarations from my functions, but this actually increased the run-time of 
> the code by a few seconds. Also, other permutations of the column orders 
> pertaining to D, T, and I led to slower performance. 
>
> I'm sure there are several issues at play here-- I'm just using Julia for 
> the first time. Any tips would be greatly appreciated. 
>

Reply via email to