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。这似乎是最优雅的方式。我认为,如果你有一个记录的构造函数,它应该为你零内存,这样记录工作起来更像类。