gpt4 book ai didi

julia - 保持/循环具有相同抽象父类型的对象集合的最佳实践 (Julia)

转载 作者:行者123 更新时间:2023-12-03 23:45:06 31 4
gpt4 key购买 nike

这是一个初学者问题,我仍在考虑“在 OOP 中”,所以如果我错过了手册中的答案或者答案很明显,我深表歉意。
假设我们有一个抽象类型,

abstract type My_Abstract_type end
以及作为该类型子代的几种具体结构类型:
mutable struct Concrete_struct1 <: My_Abstract_type end
mutable struct Concrete_struct2 <: My_Abstract_type end
...
假设我们有大量具体类型的对象,我们需要存储和循环这些对象。在 Python 中,我们可以创建一个对象列表,然后循环遍历该列表。类似地,在 C++ 中,我们可以创建一个指针数组(My_Abstract_type 类型),并循环遍历它,多态地调用所需的一切。
但是,我不知道如何在 Julia 中干净利落地做到这一点。我们可以制作一个数组 my_array::Array{My_Abstract_type,1}然后循环遍历它:
for my_object in my_array
do_something!(my_object)
end
但是,正如这里讨论的 https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-abstract-container-1 ,这带来了巨大的性能损失(在我的用例中它大约慢了 25 倍)。
一种替代方法是执行以下操作:
my_array1::Array{Concrete_struct1,1}
my_array2::Array{Concrete_struct2,1}
my_array3::Array{Concrete_struct3,1}
...
进而
for my_object in my_array1
do_something!(my_object)
end
for my_object in my_array2
do_something!(my_object)
end
for my_object in my_array3
do_something!(my_object)
end
这给了我们想要的性能,但显然是糟糕的软件工程实践,尤其是在具有大量具体类型的情况下。我们如何在不牺牲性能的情况下在 Julia 中干净地存储和循环这些对象?谢谢!

最佳答案

如果您没有超过四种具体类型,那么只需使用 Union其中,正如所描述的here在 Julia 手册中。对于这种情况,编译器将为您生成高效的代码。
如果您有很多类型,那么您可以使用数组数组:

a = [my_array1, my_array2, my_array3]
现在做
foreach(a) do x
for my_object in x
do_something!(my_object)
end
end
现在 a本身不会有具体的类型,但对匿名函数的调用应该启用代码专门化。这将产生一些开销( a 的每个元素一个动态调度),但假设每个数组的元素比类型多得多,它应该相当快。
最后,如果您想以接受大量编译成本为代价完全避免动态调度,您可以编写如下内容:
processing_fun() = nothing

function processing_fun(x, xs...)
for my_object in x
do_something!(my_object)
end
processing_fun(xs...)
end
然后调用:
processing_fun(a...)
(但如果它是有益的,则必须在您的特定情况下进行基准测试,因为它涉及递归,这也有其成本)

关于julia - 保持/循环具有相同抽象父类型的对象集合的最佳实践 (Julia),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63291899/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com