广播运营商在结构数组的字段上的(朱莉娅)

时间:2019-04-12 14:30:05

标签: julia broadcast

我有一个数组实例化的结构(相同类型)。我想更改这些结构的某个字段的值。由于性能原因,我想避免使用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)到一个新数组中,即被复制了。

是否有适当而高效的方法来做到这一点而没有循环?

谢谢

1 个答案:

答案 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,并且结构中有很多字段,则您可能会注意到其中的区别。