这是一个初学者的问题,我仍在考虑“在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
这给了我们想要的性能,但是显然是糟糕的软件工程实践,尤其是在具有大量具体类型的情况下。我们如何存储和循环遍历朱莉娅这些对象干净和不牺牲性能?谢谢!
如果你没有超过四个具体类型那么就使用Union
它们,如描述这里的朱莉娅手册。在这种情况下,编译器将为您生成高效的代码。
如果您有很多类型,则可以使用数组数组:
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...)
(但如果有好处,则必须在您的特定情况下进行基准测试,因为它涉及递归,这也有其成本)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句