Matrix 朱莉娅:如何编写修改结构字段的快速函数?

Matrix 朱莉娅:如何编写修改结构字段的快速函数?,matrix,julia,Matrix,Julia,我想写一些有效的方法来处理一些数据结构中的矩阵。我测试了外积的两个相同函数,一个在普通矩阵上运行,另一个在结构域上运行。第二个功能运行速度慢约25倍: mutable struct MyMatrix{T<:Real} mtx::Array{T} MyMatrix{T}(len) where T<:Real = new(Array{T}(len, len)) end function outerprod!(M::MyMatrix{T}, x1::Vector{T},

我想写一些有效的方法来处理一些数据结构中的矩阵。我测试了外积的两个相同函数,一个在普通矩阵上运行,另一个在结构域上运行。第二个功能运行速度慢约25倍:

mutable struct MyMatrix{T<:Real}
    mtx::Array{T}
    MyMatrix{T}(len) where T<:Real = new(Array{T}(len, len))
end

function outerprod!(M::MyMatrix{T}, x1::Vector{T}, x2::Vector{T}) where T<:Real
    # mtx = M.mtx - using local reference doesn't help
    len1 = length(x1)
    len2 = length(x2)
    size(M.mtx,1) == len1 && size(M.mtx,2) == len2 || error("length mismatch!")
    for c=1:len2, r=1:len1
        M.mtx[r,c] = x1[r]*x2[c]
    end
    M
end

function outerprod!(mtx::Array{T}, x1::Vector{T}, x2::Vector{T}) where T<:Real
    len1 = length(x1)
    len2 = length(x2)
    size(mtx,1) == len1 && size(mtx,2) == len2 || error("length mismatch!")
    for c=1:len2, r=1:len1
        mtx[r,c] = x1[r]*x2[c]
    end
    mtx
end

N = 100;
v1 = collect(Float64, 1:N)
v2 = collect(Float64, N:-1:1)
m = Array{Float64}(100,100)
M = MyMatrix{Float64}(100)

@time outerprod!(M,v1,v2);
>>  0.001334 seconds (10.00 k allocations: 156.406 KiB)

@time outerprod!(m,v1,v2);
>>  0.000055 seconds (4 allocations: 160 bytes)

mutable struct MyMatrix{T主要问题是
Array{@btime outerprod!(m,v1,v2);
2.746μs(0分配:0字节)
朱莉娅>@b时间外传!(M,v1,v2);
2.746μs(0分配:0字节)

MyMatrix对于数组的秩(即向量、矩阵或更高维数组)仍然不明确。将:
mtx::array{T}
更改为
mtx::matrix{T}
new(array{T}(len,len))
更改为
new(matrix{T}(len,len))
修复了这一问题,并使两个版本几乎同时运行(使用
@code\u warntype outerprod!(M,v1,v2);
)发现。尝试运行
@code\u warntype outerprod!(M,v1,v2)
,并对其输出感到困惑。
@code\u warntype
中的哪个文本实际上说某些数组是复制的而不是引用的?另外,请注意,如果第二个函数是
@inline
outerprod!
再次运行缓慢。关于
@code\u warntype
输出,它是彩色编码的。红色(在适当的终端上)应特别注意。请参阅
function outerprod_!(M::MyMatrix{T}, x1::Vector{T}, x2::Vector{T}) where T<:Real
    outerprod!(M.mtx, x1, x2)
    M
end

@time outerprod_!(M,v1,v2);
>>  0.000058 seconds (4 allocations: 160 bytes)