Julia -使用readdlm会导致糟糕的@code_warntype性能



以下代码来自Julia的文档,给出了@code_warntype的红色性能(Union):

julia> using DelimitedFiles
julia> x = [1; 2; 3; 4];
julia> y = [5; 6; 7; 8];
julia> open("delim_file.txt", "w") do io
writedlm(io, [x y])
end
julia> readdlm("delim_file.txt", 't', Int, 'n')
4×2 Array{Int64,2}:
1  5
2  6
3  7
4  8

julia> @code_warntype readdlm("delim_file.txt", 't', Int, 'n')
Variables
#self#::Core.Compiler.Const(DelimitedFiles.readdlm, false)
input::String
dlm::Char
T::Core.Compiler.Const(Int64, false)
eol::Char
Body::Union{Tuple{Array{_A,2} where _A,Array{AbstractString,2}}, Array{_A,2} where _A}
1 ─ %1 = Core.NamedTuple()::Core.Compiler.Const(NamedTuple(), false)
│   %2 = Base.pairs(%1)::Core.Compiler.Const(Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}(), false)
│   %3 = DelimitedFiles.:(var"#readdlm#6")(%2, #self#, input, dlm, T, eol)::Union{Tuple{Array{_A,2} where _A,Array{AbstractString,2}}, Array{_A,2} where _A}
└──      return %3

我有一个使用相同方案的代码,逻辑上返回相同的坏code_warntype性能。我找不到要修改什么来改进我的代码。谢谢你的帮助!

function create_instance(filename)
"""
This function creates instance from filename.
Example of instance of 4 nodes in filename
4
1 0.5 0.5
2 0 0
3 1 1
4 -2 4
"""
data = readdlm(filename, ' ', Float64, 'n')
n = Int(data[1,1])
x_coors = data[2:n+1, 2]
y_coors = data[2:n+1, 3]
ring_costs = zeros(Float64, n, n)
for i in 1:n
for j in 1:n
ring_costs[i,j] = dist([x_coors[i], y_coors[i]], [x_coors[j], y_coors[j]])
end
end
return n, ring_costs
end
dist(x,y) = sqrt((x[1]-y[1])^2 + (x[2]-y[2])^2)

您可以做的一件事是使用函数屏障,以防止readdlm的类型不稳定性传播到您的代码的其余部分。

类似:

# The user-facing function
function create_instance(filename)
"""
This function creates instance from filename.
Example of instance of 4 nodes in filename
4
1 0.5 0.5
2 0 0
3 1 1
4 -2 4
"""
data = readdlm(filename, ' ', Float64, 'n')
create_instance_(data)
end
# An inner function introducing a function barrier
# When this function is called, the concrete type of `data` will be known, and
# everything can be compiled efficiently.
function create_instance_(data)
n = Int(data[1,1])
x_coors = data[2:n+1, 2]
y_coors = data[2:n+1, 3]
ring_costs = zeros(Float64, n, n)
for i in 1:n
for j in 1:n
ring_costs[i,j] = dist([x_coors[i], y_coors[i]], [x_coors[j], y_coors[j]])
end
end
return n, ring_costs
end

相关内容

  • 没有找到相关文章

最新更新