Delphi 如何快速清除简单类型的记录?

Delphi 如何快速清除简单类型的记录?,delphi,Delphi,我的结构定义如下: const MaxSignalRecords=255; type TSignalRecord=record signal1 : integer; signal2 : integer; signal3 : integer; signal4 : integer; signal5 : integer; signal6 : integer; bsignal1 : Boolean; bsignal2 : Boolean

我的结构定义如下:

const
  MaxSignalRecords=255;
type
  TSignalRecord=record
   signal1  : integer;
   signal2  : integer;
   signal3  : integer;
   signal4  : integer;
   signal5  : integer;
   signal6  : integer;
   bsignal1 : Boolean;
   bsignal2 : Boolean;
   bsignal3 : Boolean;
   bsignal4 : Boolean;
   bsignal5 : Boolean;
   bsignal6 : Boolean;
  end;

TListSignals = Array[0..MaxSignalRecords-1] of TSignalRecord;
for i:=1 to 900000 do
begin
  CleartheList(MyList);
  DotheMath(MyList);
  DotheChart(MyList);
end;
此结构用于在如下算法中进行数千次计算:

const
  MaxSignalRecords=255;
type
  TSignalRecord=record
   signal1  : integer;
   signal2  : integer;
   signal3  : integer;
   signal4  : integer;
   signal5  : integer;
   signal6  : integer;
   bsignal1 : Boolean;
   bsignal2 : Boolean;
   bsignal3 : Boolean;
   bsignal4 : Boolean;
   bsignal5 : Boolean;
   bsignal6 : Boolean;
  end;

TListSignals = Array[0..MaxSignalRecords-1] of TSignalRecord;
for i:=1 to 900000 do
begin
  CleartheList(MyList);
  DotheMath(MyList);
  DotheChart(MyList);
end;
我正在寻找一种快速方法,将我的
TListSignals
的值初始化为0和
false

现在我用这个:

procedure ClearListSignals(var ListSignals:TListSignals);
var
  i :Integer;
begin
  for i := 0 to MaxSignalRecords - 1 do
  with ListSignals[i] do
  begin
   signal1   :=0;
   signal2   :=0;
   signal3   :=0;
   signal4   :=0;
   signal5   :=0;
   signal6   :=0;
   bsignal1  :=false;
   bsignal2  :=false;
   bsignal3  :=false;
   bsignal4  :=false;
   bsignal5  :=false;
   bsignal6  :=false;
  end;
end;

如何提高
ClearListSignals
过程的性能?

您可以使用
Windows
单元中的
ZeroMemory
过程

var
  MyList : TListSignals;
begin
     ZeroMemory(@Mylist,SizeOf(MyList));
end;

除了所说的
FillChar
ZeroMemory
(内部只调用FillChar),您还可以使用
bsignal:set of 1..6来减小记录的大小而不是单个布尔值,这样可以稍微加快清除速度。

您可以使用SecureZeroMemory

为了避免不必要的影响 优化编译器时,请使用 安全零记忆功能

SecureZeroMemory函数用于填充 带有零的内存块。它是 设计为更安全的版本 零内存

使用此函数而不是 当您希望确保 您的数据将被覆盖 迅速,因为编译器可以进行优化 通过删除对ZeroMemory的调用 完全是

LE:如果您的版本不包含它,您可以在Delphi中使用它:


您应该使用标准的Delphi语言函数Default()



没有黑客。。如前所述,这是个好主意。布尔值将在4或8字节的边界上对齐,所以这就像是对空间的严重浪费,因此在这种情况下会加快速度。真的,@A.Bouchez?我以为布尔值是在1字节边界上对齐的。你是说问题中记录的总大小是48而不是30?布尔值将根据编译器对齐开关对齐,除非记录已打包。另外,RAM现在非常便宜,所以我不会太担心浪费空间。@Rob:你说得对:使用sizeof(TSignalRecord)你会得到。。。32,即将有1字节对齐。然后整个记录的大小是
压缩记录
,您将得到sizeof(TSignalRecord)=30。如果设置为1..6,则sizeof(TSignalRecord)=28。浪费空间的问题不是RAM的金钱成本,而是缓存使用不当带来的速度影响。但是它在这里不是那么相关,因为布尔值的对齐方式是1。ZeroMemory只是一个围绕FillChar(,,0)的包装器。ZeroMemory是一个使用FullChar的内联,但是ZeroMemory的读取性能更好。FillChar在
系统中定义,这使得它与平台无关,ZeroMemory仅适用于Windows。FillChar也适用于Laazarus和Free Pascal以及Mac OS X。因此,如果我要读取任何ListSignals[I]的值。signal1这将等于0?避免初始赋值的好方法是,问答只针对简单类型的记录。我认为ZENsan的答案更正确。需要使用
默认值
且无直接内存攻击access@SolarWind,如果记录包含具有值的字符串,ZeroMemory将导致内存泄漏。在调用ZeroMemory之前,您可以先对记录调用Finalize()以释放字符串。@dan gph Salvador的记录中没有显示字符串,因此ZeroMemory在这种情况下工作。
SecureZeroMemory
顾名思义,是一种安全功能。它不是用于一般用途的。如果ZeroMemory检测到以后没有重用内存,优化编译器只会删除对ZeroMemory的调用,这意味着清除它没有意义。但是,内存可能包含密码,但以后不会重复使用。然后,您仍然希望确保密码已从内存中清除,以免它出现在内存转储中,或被黑客攻击访问。在OP的情况下,绝对不需要使用
SecureZeroMemory
。虽然了解函数很有用。问答只针对简单类型的记录
Default()
was。这似乎是最优雅的方式。我认为,如果你有一个记录的构造函数,它应该为你零内存,这样记录工作起来更像类。