我有一个数组实例化的结构(相同类型)。我想更改这些结构的某个字段的值。由于性能原因,我想避免使用for循环。这是一个玩具代码,用来说明我的工作:
mutable struct foo
x
end
a,b = foo(5), foo(7)
arr = [a,b]
.-(getfield.(arr,:x),1)
我希望这能将x字段放入一个数组(指向实际foo的实际x字段的指针),然后将-1应用于所有这些字段。
当我打电话给a,b
时,它们没有改变。调试后,我知道这是因为broadcast()
的getfield将这些字段具体化(Broadcast.materialize
)到一个新数组中,即被复制了。
是否有适当而高效的方法来做到这一点而没有循环?
谢谢
答案 0 :(得分:2)
如Matt B.所示,循环应该很快。但是,如果要避免循环(主要是出于方便起见),可以编写以下任意一种:
foreach(v -> v.x -= 1, arr)
(实际上是一种循环,但我不希望它比循环更快)
或使用StructArrays.jl,根据我的经验,这是很好的选择。您想要的可以实现,例如这样(使用您的arr
):
using StructArrays
arr2 = StructArray(arr)
arr2.x .-= 1
和StructArrays.jl会从1
的所有元素的字段x
中减去arr2
。
编辑而且,与对结构集合进行StructArray
循环相比,如果您执行列式操作,则可以预期for
有时会更快。字段的类型为Any
,因此这应该无关紧要,但是如果它的类型为Int
,并且结构中有很多字段,则您可能会注意到其中的区别。