Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用数组访问的循环在Julia中速度较慢_Julia - Fatal编程技术网

使用数组访问的循环在Julia中速度较慢

使用数组访问的循环在Julia中速度较慢,julia,Julia,我对具有和不具有阵列访问的循环进行了如下比较,发现两者之间的性能差异很大:1.463677[秒]与0.086808[秒] 你能解释一下如何通过数组访问来改进我的代码,以及为什么会发生这种情况吗 @inline dist2(p, q) = sqrt((p[1]-q[1])^2+(p[2]-q[2])^2) function rand_gen() r2set = Array[] for i=1:10000 r2_add = rand(2, 1) pus

我对具有和不具有阵列访问的循环进行了如下比较,发现两者之间的性能差异很大:1.463677[秒]与0.086808[秒]

你能解释一下如何通过数组访问来改进我的代码,以及为什么会发生这种情况吗

@inline dist2(p, q) = sqrt((p[1]-q[1])^2+(p[2]-q[2])^2)
function rand_gen()
    r2set = Array[]
    for i=1:10000
        r2_add = rand(2, 1)
        push!(r2set, r2_add)
    end
    return r2set
end

function test()
    N = 10000
    r2set = rand_gen()
    a = [1 1]
    b = [2 2]

    @time for i=1:N, j=1:N
        dist2(r2set[i], r2set[j])
    end

    @time for i=1:N, j=1:N
        dist2(a, b)
    end
end
test()

使
r2set
具有如下具体类型(另请参见):

现在的测试是:

julia> test()
  0.347000 seconds
  0.147696 seconds
这已经更好了

现在,如果您确实想要速度,请使用不可变类型,例如
Tuple
而不是这样的数组:

@inline dist2(p, q) = sqrt((p[1]-q[1])^2+(p[2]-q[2])^2)
function rand_gen()
    r2set = Tuple{Float64,Float64}[]
    for i=1:10000
        r2_add = (rand(), rand())
        push!(r2set, r2_add)
    end
    return r2set
end

function test()
    N = 10000
    r2set = rand_gen()
    a = (1,1)
    b = (2,2)

    s = 0.0
    @time for i=1:N, j=1:N
        @inbounds s += dist2(r2set[i], r2set[j])
    end

    @time for i=1:N, j=1:N
        s += dist2(a, b)
    end
end
test()
您将看到两者的速度相当:

julia> test()
  0.038901 seconds
  0.039666 seconds

julia> test()
  0.041379 seconds
  0.039910 seconds
注意,我添加了一个
s
,因为如果没有它,Julia会通过注意到它不起任何作用来优化循环


关键在于,如果将数组存储在数组中,那么外部数组将保存指向内部数组的指针,而对于不可变类型,数据将直接存储。

Make
r2set
具有如下具体类型(另请参见):

现在的测试是:

julia> test()
  0.347000 seconds
  0.147696 seconds
这已经更好了

现在,如果您确实想要速度,请使用不可变类型,例如
Tuple
而不是这样的数组:

@inline dist2(p, q) = sqrt((p[1]-q[1])^2+(p[2]-q[2])^2)
function rand_gen()
    r2set = Tuple{Float64,Float64}[]
    for i=1:10000
        r2_add = (rand(), rand())
        push!(r2set, r2_add)
    end
    return r2set
end

function test()
    N = 10000
    r2set = rand_gen()
    a = (1,1)
    b = (2,2)

    s = 0.0
    @time for i=1:N, j=1:N
        @inbounds s += dist2(r2set[i], r2set[j])
    end

    @time for i=1:N, j=1:N
        s += dist2(a, b)
    end
end
test()
您将看到两者的速度相当:

julia> test()
  0.038901 seconds
  0.039666 seconds

julia> test()
  0.041379 seconds
  0.039910 seconds
注意,我添加了一个
s
,因为如果没有它,Julia会通过注意到它不起任何作用来优化循环


关键是,如果您将数组存储在数组中,那么外部数组将保留指向内部数组的指针,而不可变类型的数据将直接存储。

更改
r2set
以具有具体类型的元素
r2set=Matrix{Float64}[]
@BogumiłKamiński你的意思是通过
r2set=rand>生成
r2set
(Float64,N,2)
并通过
r2set[i,:]
r2set[j,:]
访问它?我刚刚做了,花了5.705秒,这更糟糕。我猜切片会在Julia中严重恶化性能……我会给出完整的答案来解释。更改
r2set
以具有具体类型的元素
r2set=Matrix{Float64}[]
@BogumiłKamiński你是说通过
r2set=rand(Float64,N,2)
生成
r2set
并通过
r2set[i,:]和
r2set[j,:]
访问它吗?我刚刚做了,花了5.705[秒],这更糟。我想切片会严重影响Julia的性能……我会给出一个完整的答案来解释。你知道有哪些元组库支持基本操作,比如元组的+*sqrt吗?你的意思是这样的:
x,y=(1,2)、(3,4)
。然后你可以做
x.+y
x.*y
sqrt。(x) 
等。没有任何库。是的,我是认真的。实际上,在发布了那个问题后,我发现了一个库(?)命名,这有助于使用不可变向量,我想它可以按照您在回答中的建议使用。是的-StaticArrays.jl是一个非常好的库。请注意,如果数组不像其文档中解释的那样过大,那么它将非常有用。您知道有任何Tuple库支持基本操作,例如Tuple的+*sqrt吗?您的意思是类似这样:
x,y=(1,2)、(3,4)
。然后你可以做
x.+y
x.*y
sqrt.(x)
等等。没有任何库。是的,我是认真的。实际上,在发布了那个问题之后,我发现了一个库(?)命名,这有助于使用不可变向量,我想它可以按照您在回答中的建议使用。是的-StaticArrays.jl是一个非常好的库。请注意,如果数组不像文档中解释的那样过大,那么它将非常有用。