在Julia语言中,函数编译是如何复用的?

我在玩弄 Julia,我遇到了一个关于 Julia 使用的编译器/JIT 编译方案的问题。如果我写了一个函数,比如

function f(x) 
  return mapreduce(*,+,x,x)
end

那么由于这个函数作用于抽象数组,所以它的形状直到被使用才能知道,所以它不能被编译。然后,如果在函数中使用它,g,其输入是浮点数组的数组,如下所示:

function g(y) 
  return mapreduce(f,+,y)
end

或者替代地

function g2(y) 
  res = 0 
  for x in y 
    res = res + f(x)
  end
  return res 
end 

然后,当我们使用时g,比如说g([[1,2],[3,4]]),最终f会被调用。说它首先被调用[1,2]。然后对其进行编译和评估。据我所知,因为f([3,4])与 完全相同的类型f([1,2])f将被重用(因为输入都是二维数字数组)。但是,当我输入时@code_llvm(f([1,2]))@code_llvm(f([3,4]))我看到函数的名称是不同的(它们确实有一个共同的前缀,例如julia_f_,然后是一个数字)。此外,如果我@code_llvm(f([1,2]))再次打电话,我会得到另一个名字。

Julia 确实允许为每个应用程序g重用编译版本f吗?这是否取决于所涉及数组的长度?即g([w1,...,wn])每个wi都必须具有相同的长度f才能重复使用?

回答

我不太了解 Julia 的内部结构,但也许这提供了一些f仅编译一次的证据:

function f(x) 
    mapreduce(*, +, x, x)
end

function g(y) 
    mapreduce(f, +, y)
end
julia> @time g([[1, 2], [3, 4]])
  0.099061 seconds (322.72 k allocations: 19.687 MiB, 99.94% compilation time)
30

julia> @time g([[1, 2], [3, 4]])
  0.000021 seconds (11 allocations: 672 bytes)
30

第一次g运行,99.94%的时间都花在了编译上。第二次g运行,0%的时间花在编译上。请注意,如果您想从@time宏中获取编译时间,则需要 Julia v1.6+ 。


以上是在Julia语言中,函数编译是如何复用的?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>