我想了解要用xxxxx
从a
到2000
的结构初始化1000个项目数组而不是3000
的内容(即,数组的索引1表示a
是2000
,数组的索引2表示a
是2001
,依此类推),b
始终为零。
struct MyStruct
a
b
end
myArray = Vector{MyStruct}( xxxxx , 1000)
我知道我可以进行循环并分别分配值,我只是想知道Julia中是否有更快的方法。
答案 0 :(得分:5)
只需在单个帖子中收集其他用户的答案和评论即可:
与其他脚本语言(如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.a
和MyStruct.b
的类型可以是任何类型,则通常无法确切推断应在MyStruct
上执行哪种操作。即使在这种情况下,在编译器能够推断出类型为Int
的情况下,每个MyStruct
也必须包含对堆分配的Int
的引用,而不是堆栈分配。因此,只需更改即可 10倍加速
struct MyStruct
a
b
end
到
struct MyStruct
a::Int
b::Int
end
如果您希望Mystruct.a
和MyStruct.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的一大优点是循环与向量化运算一样快(有时更快)。