为了学习最新Fortran
的面向对象特性,我们编写了Delphi
的TStringList
的Fortran
版本,并链接到下面(gist.github
)。Fortran
源码模仿Delphi
源码。
此Fortran
TStringList
的功能与预期一致。然而,我的问题是,它读/写30MB文件的LoadFromFile/SaveToFile组合比Delphi的对应文件慢10倍。文件越大,Fortran的版本看起来就越差。我不会感到惊讶,因为我的业余Fortran技能。出于同样的原因,我不能理解性能下降发生在哪里,甚至从哪里开始。你能帮我评论一下吗?非常感谢您的宝贵时间!
发布于 2012-07-09 05:31:48
我相信最根本的区别在于Delphi中的"String“类型和Fortran-90中的可变长度字符串的不同性质。
在Delphi中,字符串是一种引用类型。不仅如此,它还是一个引用计数和修改时复制的类型。
那就是你写的时候:
var
a, b: String;
begin
a := 'The quick brown fox';
b := a;
b := b + ' jumped over the lazy dog.';
end;
当a被分配给b时,不会复制字符串字符。相反,b和a现在是引用相同字符串的指针,引用计数为2。
然后,当修改b时,才会生成(由编译器生成的)代码,该代码需要用自己的引用计数(1)创建一个初始的重复字符串,并从原始字符串中减去引用计数。
但是,简单地将字符串添加到列表显然不会修改它。
当TStringList读取文件内容时,将从文件中读取字符串。当字符串值随后被添加到内部列表时,字符串本身不会被复制,而只是增加引用计数,这反映了这样一个事实:即使"LoadFromFile“方法不再使用该字符串(因为它的内容已被从文件读取的下一个字符串替换),先前添加到内部列表项的字符串仍然有效。
然后,LoadFromFile必须初始化一个新字符串,以便从文件接收下一个字符串,但这是不可避免的。
不同之处在于,在Fortran版本中,除了在从文件读取每个字符串时对其进行初始化之外,还必须在将项目添加到列表时复制每个字符串。多亏了引用计数字符串类型,在Delphi代码中消除了对字符串数据的复制。
因此,Fortran代码的效率将不可避免地降低,而Delphi中引用计数的字符串类型的更高效率将对类的几乎每个领域产生影响,根据定义和设计,该类是这种字符串类型的大量“用户”。
这是除了Delphi编译器与Fortran在内存管理性能或代码生成效率方面的任何额外的相对差异之外。
https://stackoverflow.com/questions/11368809
复制相似问题