为什么Fortran版本的Delphi TStringList的业余实现比Delphi的内置版本低10倍?

时间:2012-07-06 19:52:10

标签: string performance delphi memory-management fortran

要了解最新Fortran的OO功能,Fortran Delphi TStringList gist.github版本的Fortran编写并链接在下方(Delphi )。 Fortran来源模仿TStringList

此{{1}} {{1}}按预期运行。但是,我的问题是,它读取/写入30MB文件的LoadFromFile / SaveToFile组合比Delphi的文件慢10倍。文件越大,Fortran的版本越糟糕。因为我的业余Fortran技能,我不会感到惊讶。出于同样的原因,我无法理解性能下降的位置,甚至无法从哪里开始。你能帮忙发表评论吗?非常感谢你的时间!

System.f90

SysUtils.f90

Classes_TStringList.f90

Test program of the LoadFromFile/SaveToFile

1 个答案:

答案 0 :(得分:3)

我认为最根本的区别将来自" String"在Fortran-90中键入Delphi和可变长度字符串。

在Delphi中,String是一种引用类型。不仅如此,它还是一个引用计数和复制修改类型。

那是你写的时候:

  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 被修改时,只有在那一点上(由编译器)生成代码才能创建一个初始的,重复的字符串,并带有它自己的引用count(1)并减少原始参考计数。

但是,简单地将字符串添加到列表中显然不会修改它。

TStringList 读取文件内容时,将从文件中读取字符串。当字符串值被添加到内部列表时,字符串本身不会被复制,而是仅仅增加引用计数,这反映了即使在" LoadFromFile"方法不再使用该字符串(因为它的内容已被从文件中读取的下一个字符串替换),之前添加到内部列表项的字符串仍然有效。

然后

LoadFromFile 必须初始化一个准备接收文件中下一个字符串的新字符串,但这是不可避免的。

不同之处在于,在Fortran版本中,除了在从文件中读取每个字符串时对其进行初始化,还必须在将项目添加到列表的位置复制每个字符串。由于引用计数的字符串类型,在Delphi代码中消除了字符串数据的复制。

因此,Fortran代码的效率将不可避免地降低,并且Delphi中引用计数字符串类型的更高效率将对类中的几乎每个区域产生影响 - 根据定义和设计 - 很重要"用户"这个字符串类型。

除了Delphi编译器与Fortran的内存管理性能或代码生成效率之间的任何其他相对差异之外,这将超出和超越。