Performance Julia-使用readdlm会产生糟糕的@code\u警告类型性能

Performance Julia-使用readdlm会产生糟糕的@code\u警告类型性能,performance,file,types,julia,delimited-text,Performance,File,Types,Julia,Delimited Text,来自的以下代码提供了红色性能(Union): 我有一个使用相同方案的代码,逻辑上返回相同的坏code\u warntype性能。我找不到要更改什么来改进代码。谢谢你帮助我 function create_instance(filename) """ This function creates instance from filename. Example of instance of 4 nodes in filename

来自的以下代码提供了红色性能(Union):

我有一个使用相同方案的代码,逻辑上返回相同的坏
code\u 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

可以做的一件事是使用,以防止类型不稳定性从
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


IO通常为不稳定/不确定类型。通常,您希望将类型不稳定性(即文件读取)与性能敏感代码隔离开来。您还可以使用显式类型注释强制转换到
data=…
行中的
Matrix{Float64}
。编译器可以假定数据具有该类型。@crstnbr,非常感谢您的评论。您的第二个选项建议:
data=Matrix{Float64}(readdlm(filename',Float64',\n'))
?这将红色的
联合
替换为红色的
任意
。我的意思是在行中添加
::矩阵{Float64}
。但是,我会再次尝试(例如在不同的函数中)将“数据读取”部分与“计算”部分隔离开来。(见弗朗索瓦·费沃特的答案)@crstnbr谢谢:)IO通常是不稳定/不确定类型。通常,您希望将类型不稳定性(即文件读取)与性能敏感代码隔离开来。您还可以使用显式类型注释强制转换到
data=…
行中的
Matrix{Float64}
。编译器可以假定数据具有该类型。@crstnbr,非常感谢您的评论。您的第二个选项建议:
data=Matrix{Float64}(readdlm(filename',Float64',\n'))
?这将红色的
联合
替换为红色的
任意
。我的意思是在行中添加
::矩阵{Float64}
。但是,我会再次尝试(例如在不同的函数中)将“数据读取”部分与“计算”部分隔离开来。(见弗朗索瓦·费沃特的答案)@crstnbr谢谢:)谢谢!只是一个小细节,我看到您在末尾使用了
创建\u实例
。我不知道有这样一个惯例,你能简单解释一下我什么时候应该这么做吗?另一点,我看到@code_warntype仍然返回红色联盟。我想我现在不得不忽略它了。但我发现,要知道什么时候必须忽略它,什么时候必须注意它,并不那么容易,这取决于它是IO还是编程的另一部分。也许是因为习惯了,我不知道的时候还在问这个问题?我不认为在函数名的末尾加下划线是一种普遍的惯例。在这个例子中,我只需要给这个函数起个名字,我不想想想太久。在您自己的代码中,您可能会给它起一个有意义的名字。或者,对于同一个函数,您可能有两种方法,例如
create\u instance(filename::AbstractString)
create\u instance(data::AbstractArray)
Yes
@code\u warntype
仍然会警告不稳定性,但您可以注意到它现在调用
create\u instance\ucode>。您可以重新使用
@code\u warntype
来检查
create\u instance\u
是否确实是类型稳定的。您应该知道,
create\u instance
本身仍然是类型不稳定的:您必须在调用它的性能敏感上下文中处理这个问题。例如,为了将“计算部分”与类型不稳定性隔离开来,使用与此处相同的功能屏障。再次非常感谢:)谢谢!只是一个小细节,我看到您在末尾使用了
创建\u实例
。我不知道有这样一个惯例,你能简单解释一下我什么时候应该这么做吗?另一点,我看到@code_warntype仍然返回红色联盟。我想我现在不得不忽略它了。但我发现,要知道什么时候必须忽略它,什么时候必须注意它,并不那么容易,这取决于它是IO还是编程的另一部分。也许是因为习惯了,我不知道的时候还在问这个问题?我不认为在函数名的末尾加下划线是一种普遍的惯例。在这个例子中,我只需要给这个函数起个名字,我不想想想太久。在您自己的代码中,您可能会给它起一个有意义的名字。或者,对于同一个函数,您可能有两种方法,例如
create\u instance(filename::AbstractString)
create\u instance(data::AbstractArray)
Yes
@code\u warntype
仍然会警告不稳定性,但您可以注意到它现在调用
create\u instance\ucode>。您可以重新使用
@code\u warntype
来检查
create\u instance\u
是否确实是类型稳定的。您应该知道,
create\u instance
本身仍然是类型不稳定的:您必须在调用它的性能敏感上下文中处理这个问题。例如,以与此处相同的方式使用功能屏障,以便将“计算部分”与类型不稳定性隔离。再次感谢:)