如何在Julia

时间:2019-09-16 09:18:41

标签: julia

我想了解要用xxxxxa2000的结构初始化1000个项目数组而不是3000的内容(即,数组的索引1表示a2000,数组的索引2表示a2001,依此类推),b始终为零。

struct MyStruct
    a
    b
end

myArray = Vector{MyStruct}( xxxxx , 1000)

我知道我可以进行循环并分别分配值,我只是想知道Julia中是否有更快的方法。

2 个答案:

答案 0 :(得分:5)

只需在单个帖子中收集其他用户的答案和评论即可:

不,没有比在朱莉娅(Julia)中循环更快的了

与其他脚本语言(如Python和R)不同,Julia中的循环速度很快。实际上,其他“矢量化”操作(例如广播)是根据Julia循环本身实现的。因此,一种快速的解决方案可能是:

function initialize_vector(range::AbstractRange)
    v = Vector{MyStruct}(undef, length(range))
    @inbounds for i in eachindex(range)
        v[i] = MyStruct(range[i], 0)
    end
    return v
end

广播既方便又方便

广播几乎或有时与循环一样快,并且通常更简洁和方便。在这种情况下,可以编写上面的功能initialize_vector

initialize_vector(range::AbstractRange) = MyStruct.(range, 0)

基准测试表明这两个功能的速度几乎相同。

记住要在结构中键入字段以获取更快的代码

Julia依靠类型的准确推断来创建快速,专业的代码。如果MyStruct.aMyStruct.b的类型可以是任何类型,则通常无法确切推断应在MyStruct上执行哪种操作。即使在这种情况下,在编译器能够推断出类型为Int的情况下,每个MyStruct也必须包含对堆分配的Int的引用,而不是堆栈分配。因此,只需更改即可 10倍加速

struct MyStruct
    a
    b
end

struct MyStruct
    a::Int
    b::Int
end

如果您希望Mystruct.aMyStruct.b的类型能够变化,则可以创建参数MyStruct,如下所示:

struct MyStruct{T}
    a::T
    b::T
end

答案 1 :(得分:2)

通过.进行广播在这里效果很好。您还可以为b提供一个向量/集合:

struct MyStruct
    a
    b
end

struct_vec = [MyStruct.(2000:3000, 0)...]
struct_vec2 = [MyStruct.(2000:3000, 0:1000)...]

这将导致1001-element Array{MyStruct,1}

修改 如评论中所述,...拼写和[]不是必需的。此外,为了提高struct的性能,您可以指定其字段的类型信息:

struct MyEfficientStruct{T}
    a::T
    b::T
end

struct_vec = MyEfficientStruct.(2000:3000, 0)
struct_vec2 = MyEfficientStruct.(2000:3000, 0:1000)

最后,虽然广播语法比循环更简洁,但是Julia的一大优点是循环与向量化运算一样快(有时更快)。