我正试图弄清楚,如果试图节省内存,使用"[type]的压缩数组"是否会有好处。
你可以在Win32位上读到,事实并非如此:http://docwiki.embarcadero.com/RADStudio/XE4/en/Internal_Data_Formats#Dynamic_Array_Types
一般来说,在我看来,动态数组的运行时代码将是fasterif,从不在项之间使用填充。但是,由于我相信Delphi/64bit中的默认对齐是8字节,因此似乎有一天你可能无法指望动态数组包含例如布尔值,默认情况下"打包"
首先,我认为您需要小心阅读文档。它没有得到一致的更新,而且某些部分似乎是Win32特有的,这一事实决不能用来推断Win64的不同。事实上,对于您的问题中提出的问题,32位和64位之间没有实质性差异。
对于Delphi,在数组上使用packed不会改变连续元素之间的填充。数组的两个相邻元素之间的距离等于SizeOf(T),其中T是元素类型。无论使用填充改性剂,这一点都成立。在数组上使用packed甚至不会影响数组的对齐。
因此,为了完全清楚和明确,packed
在数组上使用时根本没有影响。编译器处理压缩数组的方式与处理非压缩数组的方法完全相同。
这一说法似乎与文件不一致。文件说明:
结构化类型的对齐
默认情况下,结构化类型中的值在单词或双字边界,实现更快的访问。
但是,您可以通过包含保留的当您声明一个结构化类型时,word压缩。压缩的单词指定压缩数据存储。下面是一个示例声明:
type TNumbers = packed array [1..100] of Real;
但考虑一下这个程序:
{$APPTYPE CONSOLE}
type
TNumbers = packed array [1..100] of Real;
type
TRec = record
a: Byte;
b: TNumbers;
end;
begin
Writeln(Integer(@TRec(nil^).a));
Writeln(Integer(@TRec(nil^).b));
Readln;
end.
使用DelphiXE2,其输出为:
08.
所以,将packed
和数组一起使用并不会修改类型的对齐方式,这和文档不符。
注意,上面的程序,当用Delphi6编译时,有输出
01.
因此,编译器似乎发生了变化,但文档并没有跟上。
这里可以找到一个相关的问题:Delphi中的数组和压缩数组之间有什么区别吗?但请注意,Barry Kelly(编写答案时是Embarcadero编译器工程师)的答案并没有提到编译器行为的变化。
一般来说,在我看来,如果从不在项之间使用填充,运行时代码会更快。
如上所述,对于数组,数组元素之间从不存在填充。
我相信Delphi/64bit中的默认对齐方式是8字节。
对齐由数据类型决定,与目标体系结构无关。因此布尔值的对齐方式为1。一个单词的对齐方式为2。整数的对齐方式为4。Double的对齐方式为8。这些对齐值在32位和64位上是相同的。
对齐对性能有着巨大的影响。如果您关心性能,一般来说,您应该永远不要打包数据结构。如果您希望最小化结构(类或记录)的大小,请将较大的元素放在首位,以最小化填充。这可以提高性能,但也可能使性能恶化
但没有一条硬性规定。我可以想象,如果打包的东西几乎从未被访问过,那么打包可以提高性能。事实上,我可以更容易地想象,将结构中元素的顺序更改为与元素相关的组可以提高性能。