Julia 中 for 循环的性能
Performance of for loops in Julia
我尝试了以下代码,但性能差异很大
在代码之间。听说顶层的代码不适合数值计算,但是性能好像也取决于是否
顶级变量(此处为 N)出现在 for 循环的范围内。
避免此类顶级变量总是更好吗?
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()
使用 Julia 0.3.7(在 Linux x86_64 上)获得的结果是
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)
采用"Is it always better to avoid such top-level variables?"字面量的答案当然是"No, it depends",但有用的注释是将全局变量声明为常量
const N = 10000000
使案例 2 与案例 3 一样快。
编辑:我应该补充一点,案例 2 的问题是顶层 N
使得范围 1:N
和迭代器变量 j
的类型不稳定,即使累加器变量 y
是本地的。这个问题更灵活的解决方法是
let
y = 0.0
for j = 1:(N::Int)
y += float( j )
end
y
end
我尝试了以下代码,但性能差异很大 在代码之间。听说顶层的代码不适合数值计算,但是性能好像也取决于是否 顶级变量(此处为 N)出现在 for 循环的范围内。 避免此类顶级变量总是更好吗?
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()
使用 Julia 0.3.7(在 Linux x86_64 上)获得的结果是
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)
采用"Is it always better to avoid such top-level variables?"字面量的答案当然是"No, it depends",但有用的注释是将全局变量声明为常量
const N = 10000000
使案例 2 与案例 3 一样快。
编辑:我应该补充一点,案例 2 的问题是顶层 N
使得范围 1:N
和迭代器变量 j
的类型不稳定,即使累加器变量 y
是本地的。这个问题更灵活的解决方法是
let
y = 0.0
for j = 1:(N::Int)
y += float( j )
end
y
end