除了“打包”记录之外什么都没有 - 我应该修复它吗?

时间:2011-10-11 22:10:47

标签: delphi delphi-7 record packed

在审阅我们的旧版Delphi 7程序中的一些代码时,我注意到在有记录的地方,它都标有packed。这当然意味着记录是逐字节存储的,并且没有对齐以便CPU访问更快。包装似乎是盲目地完成的,试图超越编译器或其他东西 - 基本上重视几个字节的内存而不是更快的访问

示例记录:

TFooTypeRec = packed record
    RID                 : Integer;
    Description         : String;
    CalcInTotalIncome   : Boolean;
    RequireAddress      : Boolean;
end;

我应该解决这个问题并使每条记录正常或“不”打包吗?或者使用现代CPU和内存这可以忽略不计,可能浪费时间?拆包可能导致任何问题吗?

4 个答案:

答案 0 :(得分:21)

如果没有完全理解每个打包记录在应用程序代码中的使用方式,就无法回答这个问题。它与询问“我是否应该将此变量声明从Int64更改为字节?”

相同

不知道该变量的预期值和维持答案所需的值可能是肯定的。或者可能不是。

同样在你的情况下。如果记录需要打包,那么它应该 left 打包。如果不需要包装,那么不包装就没有害处。如果您不确定或无法分辨,那么最安全的做法是将它们保留原样。

作为做出此决定的指南(如果您决定继续),需要或建议记录包装的情况包括:

  • 记录值的持久性
  • 使用[可能]不同编译的代码共享记录值
  • 与外部定义的结构的严格兼容性
  • 故意在不同结构化的内存上覆盖类型布局

这不一定是详尽的清单,这些都有一个共同点:

  • 包含相邻字节中的一系列值的记录,记录的任何潜在生产者或消费者都必须依赖这些值,而不会受到编译器或其他因素的干扰

我建议您(如果可能和实际)确定包装在每种情况下的用途,并将相应的文档添加到记录声明本身,以便将来有相同问题的任何人都不需要经历这个发现过程,例如:

  type
    TSomeRecordType = packed record
      // This record must be packed as it is used for persistence
      ..
    end;

    TSomeExternType = packed record
      // This record must be packed as it is required to be compatible
      //  in memory with an externally defined struct (ref: extern code docs)
      ..
    end;

答案 1 :(得分:7)

使用打包记录的主要思想是而不是,您可以节省几个字节的内存!相反,它是关于保证变量是你期望它们在内存中的位置。如果没有这样的保证,就不可能(或者至少很难)在堆上手动管理内存并写入和读取文件。

因此,如果您“解包”记录,程序可能会出现故障!

答案 2 :(得分:1)

如果记录以打包方式存储/检索,或以任何方式转移到预期打包的接收方,则不要更改。

更新:

您的示例中声明了一个字符串类型。它看起来很可疑,因为将记录存储在二进制文件中不会保留字符串内容。

答案 3 :(得分:0)

  • 打包记录的长度与成员的大小完全相同。
  • 没有优化打包记录(对齐 - >因此更高)以获得更好的性能。