哪种处理记录数据更有效?

Dia*_*ian 7 delphi

什么是更有效的方式?

FUserRecords[I].CurrentInput:=FUserRecords[I].CurrentInput+typedWords;
Run Code Online (Sandbox Code Playgroud)

要么

var userRec: TUserRec;
...
userRec:=FUserRecords[I];
userRec.CurrentInput:=userRec.CurrentInput+typedWords;
FUserRecords[I]:=userRec;
Run Code Online (Sandbox Code Playgroud)

Nat*_*Nat 10

在您描述的情况下,第一个示例将是最有效的.

记录是值类型,因此当您执行此行时:

userRec:=FUserRecords[I];
Run Code Online (Sandbox Code Playgroud)

实际上,您正在将数组中记录的内容复制到局部变量中.当您执行相反操作时,您将再次复制信息.如果您正在迭代数组,如果您的数组和记录非常大,这可能会变得非常慢.

如果你想沿着第二条路走下去,为了加快速度,你可以使用指向记录的指针直接操作数组中的记录,如下所示:

type
  TUserRec = record
    CurrentInput: string;
  end;
  PUserRec = ^TUserRec;

var
  LUserRec: PUserRec;
...
LUserRec := @FUserRecords[I];
LUserRec^.CurrentInput := LUserRec^.CurrentInput + typedWords;
Run Code Online (Sandbox Code Playgroud)

(正如评论中所讨论的,插入符号(^)是可选的.我只是为了完整性而添加它们).

当然我应该指出,如果实际存在性能问题,你真的只需要这样做.在手动编写这些优化之前,最好对您的应用程序进行概要分析.

编辑:关于您正在研究的性能问题的所有讨论的一个警告是,如果记录中的大多数数据都是字符串,那么在您显示的示例中丢失的大部分性能都将在字符串连接中,而不是记录操纵.

此外,字符串基本上作为指针存储在记录中,因此记录实际上将是任何整数等的大小,加上字符串指针的大小.因此,当您连接到字符串时,它不会增加记录大小.您基本上可以将代码的字符串操作部分视为记录操作的单独问题.

您在下面的评论中提到,这是用于存储来自多个键盘的输入,我无法想象您将在阵列中拥有超过5-10个项目.在这个规模上,执行这些步骤来优化代码并不会真正提高速度.

我相信你的第一个例子和上面的指针使用代码最终会得到大致相同的性能.您应该使用最容易阅读和理解的内容.

N - [

  • 是的,在这种情况下,指针会更高效*.我还要指出[解释] dereference运算符在Delphi中是完全可选的.LUserRec ^ .xyz可以简单地写成LUserRec.xyz并自动解除引用.对于那些因这种捷径引入"模棱两可"而感到骇然的人,还有什么可能意味着什么?请注意,我们一直使用对象引用变量(这是另一个名称的指针)执行此操作. (3认同)
  • 使用第一个选项实际上是唯一的选择.正如Nat指出记录是"值",你不想复制它们.使用指针实现选项2只会模糊代码并且不会带来任何好处(甚至可能会使事情变得缓慢).当您使用数组时,Delphi通常会计算到所需字段的偏移量并使用"基于索引的寻址模式":这是一个读取/写入字大小字段的汇编指令.如果用显式指针替换它,你将使用至少两个指令+ 1个额外的寄存器来完成相同的工作. (3认同)
  • @ldsandon:是的,P1:= P2 <> P1 ^:= P2 ^ ...但是P1.xyz:= P2.xyz完全没有意义,不应该编译.要使其编译,您必须将^添加到取消引用.但是我们不必这样做,那么"P"是一个混淆的指针(即一个对象引用),那么为什么我们不应该在它没有被混淆时这样做呢?这完全没有必要,也不会导致混淆或含糊不清.你自己很困惑......你觉得让Delphi为你提起任何数量的自动解除引用案件是完全合理的,但是在这个案例中却抱怨了吗? (2认同)