Julia-pi近似

Julia-pi近似,julia,Julia,我的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时

我的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秒)。为什么会这样

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文档部分中两个非常重要的段落:

全局变量可能有其值,并且 因此,它的类型在任何时候都会发生变化。这就给我们的工作带来了困难 编译器使用全局变量优化代码。变量应该 尽可能是本地的,或作为参数传递给函数

宏(或其函数变量代码_warntype())可以 有时有助于诊断与类型相关的问题

@code\u 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

请注意,
m
sum
上的类型注释对于速度不是必需的。类型注释(::Int,::Float64)实际上对此处的性能没有任何影响。(添加无用的类型注释是一个常见的错误。)还要注意,您忘记了返回总和。(LLVM实际上可能会优化整个循环!)
julia> @time piaprox(100000000)
  0.746795 seconds (11.11 k allocations: 400.294 KB, 0.45% gc time)
1.644934057834575