在windows中内存的分配一次是4个字节的。而packed按字节进行内存的申请和分配,这样速度要慢一些,因为需要额外的时间来进行指针的定位。因此如果不用packed的话,delphi将按一次4个字节的方式申请内存,因此如果一个变量没有4个字节宽的话也要占4个字节!这样就浪费了,你可以用packed关键字取消这种优化。

例子:  
type  
         myrec   =   packed   record  
         n1   :   integer;         4个字节  
         n2   :   shortint;       1个字节  
end;  
sizeof(myrec)------     5  
  
type  
         myrec   =   record  
         n1   :   integer;  
         n2   :   shortint;  
end;  
sizeof(myrec)------     8

Record的数据各个字节都是对齐的,数据格式比较完整,所以这种格式相对packed占用的内存比较大,
但是因为格式比较整齐,所以电脑读取这个类型的数据的时候速度比较快。

而Packed Record对数据进行了压缩,节省了内存空间,当然他的速度也变的慢了。

type  
      //    Declare    an    unpacked    record  
      TDefaultRecord    =    Record  
          name1        :    string[4];  
          floater    :    single;  
          name2        :    char;  
          int            :    Integer;  
      end;  
      //    Declare    a    packed    record  
      TPackedRecord    =    Packed    Record  
          name1        :    string[4];  
          floater    :    single;  
          name2        :    char;  
          int            :    Integer;  
      end;  
var  
      defaultRec    :    TDefaultRecord;  
      packedRec      :    TPackedRecord;  
begin  
      ShowMessage('Default    record    size    =    '+IntToStr(SizeOf(defaultRec)));  
      ShowMessage('Packed    record    size    =    '+IntToStr(SizeOf(packedRec)));  
end;  
  
    Default    record    size    =    20  
    Packed    record    size    =    14  

不过,对于现在的操作系统来,packed Record 节省的那些空间已不用考虑他了。除了做DLL(不用packed容易造成内存混乱)和做硬件
编程时(比如串口)编程时必须用到packed Record,其它情况都可以用Record

 

呵呵。 PIPI给我上了一课。 多谢。我犯了形而上学想当然的错误
专门试了一下
procedure TForm1.Button1Click(Sender: TObject);
var a: packed array[1..10] of Integer;
    b: array[1..10] of Integer;
begin
a[1] := 1;
a[2] := 256;
a[3] := 65535;
a[4] := 65535;
a[5] := 100000;
Edit1.Text := IntToStr(Sizeof(a));

b[1] := 1;
b[2] := 256;
b[3] := 65535;
b[4] := 65535;
b[5] := 100000;
Edit2.Text := IntToStr(Sizeof(b));
end;
两者是同样的内存尺寸

 

有 Packed 的占用内存小,但是速度慢一点
没 Packed 的占用内存大,但是速度快一点
比如说,有一个结构t,你又使用了一个a很大的array of t,那么可能要节省一点内存
但是,如果你不是申请很多t的实例,那么不用节省几个byte,要知道现在内存很大了
1M那可是 100多万 byte啊
另外,说一下为什么align了就快:
比如一个integer 4个字节,如果他的气死地址是4的倍数,0、4、8、12……
那么一次时钟(还是总线?)周期就可以读写它,
如果起始于1、2、3,那么要分2个周期才能读写它

用了packed后数据会压缩,但速度变慢。这就是两者的区别!

比如
packed record
aaa:byte
bbb:inetegr
ccc:byte
end //只占用6字节


record
aaa:byte
bbb:inetegr
ccc:byte
end //占用12个字节

delphi缺省使用 没有packed 的

Packed 还有一个要考虑的地方就是,如果你要做DLL的话,那么参数的传递就要用Packed的,否则很容易造成内存的写乱.

 


一般為了效率考量, structure, array.. 之類的資料, complier 會把記億體做所謂 alignment (對齊?) 的調整, 這樣存取時會比較快速

舉個例子, 沒有特別調整 complier 的 alignment 時:

 

type
   TTest = record
     x: integer; // 4 bytes
     y: char;    // 1 byte, 但實際上會是占 4 bytes
   end;


你可以做一個簡單的測試, sizeof(TTest) 會等於 8

但如果加上 packed 時, 則 complier 不做 alignment,
這時就會是你真正定義的長度了:

 

type
   TTest = packed record
     x: integer; // 4 bytes
     y: char;    // 1 byte, 實際上也會是占 1 byte
   end;


跑出來的結果, sizeof(TTest) 會等於 5

一般是不需 packed, 但如果需要這樣的應用 (如與dll接軌, 硬體控制),
就可能需要拿出來使用..

PS: packed 相當於 {$A1}

s07452你好:
宣告記錄型態(record),預設的編譯方式會將各欄佔用的記憶體長度以方便CPU存取的方式向word或double-word佔用空間大小對齊,以得到較佳的存取速度。如果宣告時使用packed record,則按照實際各欄佔用空間配置,但存取速度較差。你可以參考HELP裡關於packed的說明。

posted on 2013-01-11 09:33  幻劫  阅读(274)  评论(0编辑  收藏  举报