通过赋值进行隐式分配与显式分配/释放

Joh*_*hnE 1 fortran

如果我的编译器兼容Fortran 2003,我可以重新分配可分配变量或数组,而无需显式解除分配/分配过程,如Fortran 中分配时自动数组分配中所述。例如

integer, allocatable :: i(:)

i = [1,2,3]
i = [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)

与旧的(Fortran 90)方式相比:

if( allocated(i) ) deallocate(i)
allocate(i(3))
i = [1,2,3]
if( allocated(i) ) deallocate(i)
allocate(i(5))
i = [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)

这种新技术有什么优点和缺点?这肯定是比旧方法更简洁的代码。但有理由选择旧方式吗?我在代码示例中仍然看到旧方法比新方法多得多,但这也许只是因为 Fortran 90 的使用仍然多于 Fortran 2003。

作为快速计时检查,我在 gfortran 4.8.5 下循环上述代码 100,000,000 次,发现较新的方式似乎也更快,运行时间约为 4 秒(新方式),而运行时间为 6 秒(旧方式)。相反,在下面的评论中,@roygvib 得到的结果与 gfortran 8.2 基本相反。

另外,请注意这里最近对该问题的讨论: Fortran 讨论组

Vla*_*r F 5

我会列出差异,什么是优点或缺点是主观的。

编译器必须检查每个整个数组分配的正确边界 - 但这无论如何都必须发生,即使您不使用重新分配。除非您在某些编译器中完全禁用此标准功能。

对于那些不习惯动态语言的人来说,大多数赋值都会进行一些分配,这可能是一个重要的事实,在deallocatereallocate语句中,重新分配实际上正在发生,这是明确可见的。

通过自动重新分配,编译器可能会使用realloc,特别是在像a = [a, 1]. 但据我所知,编译器目前还没有这样做。尽管如此,如果旧数组适合的话,malloc通常会重新使用旧数组所在的内存。