gpt4 book ai didi

julia - julia 的 View 函数的幕后发生了什么? [3, :] = view(a, 1, :) vs a[3, :] = a[1, :]

转载 作者:行者123 更新时间:2023-12-03 13:37:30 36 4
gpt4 key购买 nike

我认为 View 函数的工作方式类似于 C++ 中的引用,基本上两个变量都指向同一块内存。
为什么这样做:

julia> a = [1 2 3; 4 5 6; 7 8 9]
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9


julia> b = view(a, 1, :)
3-element view(::Array{Int64,2}, 1, :) with eltype Int64:
1
2
3

julia> b[1] = 100
100

julia> a
3×3 Array{Int64,2}:
100 2 3
4 5 6
7 8 9

julia> a[1, 3] = 200
200

julia> b
3-element view(::Array{Int64,2}, 1, :) with eltype Int64:
100
2
200
基本上你改变一个,另一个也改变,反之亦然。但这并没有相同的效果:
julia> a = [1 2 3; 4 5 6; 7 8 9]
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9

julia> a[3, :] = view(a, 1, :)
3-element view(::Array{Int64,2}, 1, :) with eltype Int64:
1
2
3

julia> a
3×3 Array{Int64,2}:
1 2 3
4 5 6
1 2 3

julia> a[1, 1] = 100
100

julia> a
3×3 Array{Int64,2}:
100 2 3
4 5 6
1 2 3

julia> a[3, 1] = 200
200

julia> a
3×3 Array{Int64,2}:
100 2 3
4 5 6
200 2 3
我的问题:这相当于做: a[3, :] = a[1, :] ?是否有任何性能优势?第二种情况的幕后发生了什么?
任何反馈表示赞赏!

最佳答案

您可以检查在这种情况下复制是否发生,例如通过运行此代码:

julia> a = rand(3, 10^6);

julia> b = view(a, 1, :);

julia> @time a[3, :] = b; # I have already compiled the code earlier
0.005599 seconds (3 allocations: 7.629 MiB)

julia> bc = copy(b);

julia> @time a[3, :] = bc; # I have already compiled the code earlier
0.002189 seconds (1 allocation: 16 bytes)
原因是函数中的 Julia _unsafe_setindex! (也就是最后被你做的操作调用了),是不是 x′ = unalias(A, x) .此操作意味着检查源数组和目标数组是否保证在编译时不共享内存。在这种情况下,编译器无法证明这一点,因此会发生复制。
为了使您想要的操作高效,您可以做的就是使用循环(如您所知,实际上别名不会通过您定义操作的方式发生;我正在使用 View ,但当然您可以只读写直接来自 a 而不创建 b ):
function fastcopy!(a)
@assert size(a, 1) > 2
b = view(a, 1, :)
@inbounds @simd for i in eachindex(b)
a[3, i] = b[i]
end
end
在这里你有时间:
julia> @time fastcopy!(a)
0.001895 seconds

关于julia - julia 的 View 函数的幕后发生了什么? [3, :] = view(a, 1, :) vs a[3, :] = a[1, :],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65979923/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com