我的pi近似代码与官方页面非常相似:
function piaprox()
sum = 1.0
for i = 2:m-1
sum = sum + (1.0/(i*i))
end
end
m = parse(Int,ARGS[1])
opak = parse(Int,ARGS[2])
@time for i = 0:opak
piaprox()
end
当我尝试比较C和Julia的时间时,Julia明显变慢,m = 100000000几乎为38秒(C的时间为0.1608328933秒)。为什么会这样?
答案 0 :(得分:13)
julia> m=100000000
julia> function piaprox()
sum = 1.0
for i = 2:m-1
sum = sum + (1.0/(i*i))
end
end
piaprox (generic function with 1 method)
julia> @time piaprox()
28.482094 seconds (600.00 M allocations: 10.431 GB, 3.28% gc time)
我想提一下julia文档的Performance Tips部分中的两个非常重要的段落:
Avoid global variables全局变量可能有其值,而且 因此它的类型,随时都有变化。这使得它很难 编译器使用全局变量优化代码。变量应该 尽可能在本地,或作为函数的参数传递.....
宏@code_warntype(或其函数变体code_warntype())可以 有时有助于诊断类型相关的问题。
julia> @code_warntype piaprox();
Variables:
sum::Any
#s1::Any
i::Any
从@code_warntype
输出可以清楚地看出,编译器无法识别piaprox()
中的局部变量类型。所以我们尝试声明类型并删除全局变量:
function piaprox(m::Int)
sum::Float64 = 1.0
i::Int = 0
for i = 2:m-1
sum = sum + (1.0/(i*i))
end
end
julia> @time piaprox(100000000 )
0.009023 seconds (11.10 k allocations: 399.769 KB)
julia> @code_warntype piaprox(100000000);
Variables:
m::Int64
sum::Float64
i::Int64
#s1::Int64
修改强>
正如@ user3662120评论的那样,答案的超快行为是错误的结果,没有返回值,LLVM可能会忽略for循环,通过添加@time
结果的返回行:
julia> @time piaprox(100000000)
0.746795 seconds (11.11 k allocations: 400.294 KB, 0.45% gc time)
1.644934057834575