在Fortran 90中,使用2D数组和派生类型的数组有何区别?

7
假设您需要一个大小相同的数组列表。从性能角度考虑,使用2D数组是否更好:
integer, allocatable :: data(:,:)

或者是派生类型的数组:
type test
    integer, allocatable :: content(:)
end type
type(test), allocatable :: data(:)

当然,对于不同大小的数组,我们没有选择。但是这两种情况之间的内存管理如何?另外,它们中的哪一个是良好的代码实践呢?
2个回答

10

选择使你的头脑在你脑中的问题代码中的解决方案之间跨越的概念距离最小化的实现。这种方法的力量会随着年龄增长而增加,无论是你代码的年龄(良好的概念设计是未来开发的坚实基础)还是你自己的年龄(理解代码所需的努力越少,你就能保持精神上的足够健康来理解它的时间越长)。

至于关于内存管理方式不以意见为基础的部分... 我幼稚的期望是大多数编译器在大多数情况下将为你的第一个大纲分配连续的内存,并且可能不会为第二个分配。但我并不在乎这一点,也不认为你应该在乎。我并不是建议你对发生的事情不感兴趣,而是你应该更关注第一段提到的事情。


1
越想越觉得,“最小化概念距离”比一些抽象的“最简单”的度量更重要。 - Jonathan Dursi
这就是关键!你必须在可读性和性能之间找到平衡点... - Girardi

5
一般来说,您应该使用最简单的数据结构来解决问题。如果一个二维矩形数组满足您的需求 - 对于许多科学计算问题,对于使用Fortran的问题来说,它确实是一个不错的选择 - 那么这就是您想要的选择。
二维数组在内存中是连续的,这通常会使访问更快,原因是缓存和一个较少的间接级别;二维数组还能让您执行像 data = data * 2data = 0. 这样的操作,而数组嵌套数组的方法则不行 [编辑以补充: 尽管如IanH在评论中指出的那样,您可以创建一种定义类型和定义这些类型上的操作来允许此操作]。这些优点足以使人们考虑将具有“不规则数组”的情况实现为矩形二维数组,即使在预期行长度的范围不是很大的情况下也是如此。

2
请考虑所定义的操作提供的功能,特别是涉及乘法和数组赋值的评论。 - IanH
还不错,但使用内置的2D数组仍然是更快(a)更少临时变量的可能性(例如,d=a*b+c),(c)同时在两个维度上进行切片,所有这些(d)都是免费的。在某些情况下,仍然会更明智地使用数组-数组,但如果您不需要额外的通用性,则使用简单情况可能是有意义的。 - Jonathan Dursi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接