将 @time 报告的 Julia 中大向量的分配加倍

Gra*_*ale 4 time allocation julia

考虑以下 Julia 中的简单程序:

function foo_time(x)
    @time x.^2
    return nothing
end
n = 1000;
foo_time(collect(1:n));
Run Code Online (Sandbox Code Playgroud)

如果我在控制台中运行它,则会@time报告 1 个分配,这正是我所期望的。但是,如果我更改n10000,则@time报告 2 个分配。

更重要的是,如果我在没有句法循环融合的情况下(换句话说,没有点)将函数链接在一起,那么我似乎得到了预期分配的两倍。例如, write(x + x).^2 + x而不是用x.^2产生 3 个分配n = 1000,但它用 产生 6 个分配n = 10000。(尽管该模式并不严格继续:例如,(x + x + x).^2只为 产生 5 个分配n = 10000。)

为什么向量的大小会影响分配发生的次数?这里发生了什么?

这发生在 JupyterLab 控制台和普通的 Julia REPL 中。

Mat*_* B. 6

为什么有一个小向量分配和两个大向量分配?

真的,这并不重要,它是数组如何工作的内部细节。本质上,Julia 有两个部分Array:内部标头(跟踪数组的维度和元素类型等)和数据本身。当数组较小时,将这两个数据段捆绑在一起有优势,但当数组较大时,将它们分开有优势。这不是广播的事情,它只是数组分配的事情:

julia> f(n) = (@time Vector{Int}(undef, n); nothing)
f (generic function with 1 method)

julia> f(2048)
  0.000003 seconds (1 allocation: 16.125 KiB)

julia> f(2049)
  0.000003 seconds (2 allocations: 16.141 KiB)
Run Code Online (Sandbox Code Playgroud)

然后希望您能明白为什么这会导致在涉及临时对象时为大型数组分配的数量翻倍——每个数组的头有一个,每个数组的数据有一个。

简而言之——不要太担心分配的数量。有时分配实际上可以提高性能。然而,当您看到大量分配时,尤其是当您看到它们与数组中的元素数量成正比时,需要担心。