Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance of for loops in Julia

I tried the following codes but the performance is extremely different among codes. I heard that codes at the top level are not suited for numerical computation, but the performance also seems to depend on whether top-level variables (here, N) appear in the range of for-loops. Is it always better to avoid such top-level variables?

N = 10000000

# case1 (slow)
x = 0.0
@time for k = 1:N
    x += float( k )
end

# case2 (slow)
@time let
    y = 0.0
    for j = 1:N
        y += float( j )
    end
end

# case3 (very fast)
@time let
    n::Int64
    n = N
    z = 0.0
    for m = 1:n
        z += float( m )
    end
end

# case 4 (slow)
function func1()
  c = 0.0
  for i = 1:N                                             
    c += float( i )
  end
end

# case 5 (fast)
function func2( n )                                          
  c = 0.0
  for i = 1:n
    c += float( i )
  end
end

# case 6 (fast)
function func3()
  n::Int
  n = N
  c = 0.0
  for i = 1:n                                   
    c += float( i )
  end
end

# case 7 (slow)
function func4()
  n = N        # n = int( N ) is also slow                                  
  c = 0.0
  for i = 1:n
    c += float( i )
  end
end

@time func1()
@time func2( N )
@time func3()
@time func4()

The result obtained with Julia 0.3.7 (on Linux x86_64) is

elapsed time: 2.595440598 seconds (959985496 bytes allocated, 10.70% gc time)
elapsed time: 2.469471127 seconds (959983688 bytes allocated, 11.49% gc time)
elapsed time: 1.608e-6 seconds (16 bytes allocated)
elapsed time: 2.535243279 seconds (960021976 bytes allocated, 11.21% gc time)
elapsed time: 0.002601149 seconds (75592 bytes allocated)
elapsed time: 0.003471583 seconds (84456 bytes allocated)
elapsed time: 2.480343146 seconds (960020752 bytes allocated, 11.48% gc time)
like image 738
roygvib Avatar asked Apr 26 '15 12:04

roygvib


1 Answers

The answer taking "Is it always better to avoid such top-level variables?" literal is of course "No, it depends", but a useful remark is that declaring global variables as constant

const N = 10000000

makes case 2 as fast as case 3.

Edit: I should add that the problem for case 2 is that the top level N makes the type of the range 1:N and iterator variable j unstable, even if the accumulator variable y is local. A more flexible fix for this problem is

   let
       y = 0.0
       for j = 1:(N::Int)
           y += float( j )
       end
       y
   end
like image 168
mschauer Avatar answered Sep 23 '22 06:09

mschauer