• packed record与record区别


    在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的說明。

  • 相关阅读:
    解析XML
    事务
    js小工具
    plsql用过的流程语句
    查询语句
    存储过程
    用过的CRT命令
    mysql常用命令
    Spirng MVC demo 完整示例01 环境搭建
    jmeter多个http请求串联
  • 原文地址:https://www.cnblogs.com/jieke/p/2855793.html
Copyright © 2020-2023  润新知