只有“包装”记录 - 我应该修复它吗?

只有“包装”记录 - 我应该修复它吗?

问题描述:

虽然在我们传统的Delphi 7程序中查看了一些代码,但我注意到,在任何地方都有一个记录标记为packed。这当然意味着记录以字节为单位进行存储,而不是按CPU的访问速度进行对齐。包装似乎已经做盲目的尝试智取编译器或东西 - 基本估价,而不是更快的存取内存的几个字节只有“包装”记录 - 我应该修复它吗?

的示例记录:

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

我应该解决这个问题,并使每个记录正常或“不”包装?或者与现代的CPU和内存是可以忽略不计,可能是浪费时间?解包后是否有任何问题?

+2

此外,在您给出的示例中,解包不会导致更快的访问:前两个字段已经对齐,布尔值是字节且不需要对齐。如果访问的数据不再适合CPU高速缓存(L1在现代CPU上仍然只有几十千字节),那么更大的对齐结构可能效率更低。因此,您冒险破坏可能会降低性能的代码。 –

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

不知道该变量将被预期和需要维护答案可能是什么值。或者它可能不是。

同样在你的情况。如果一个记录需要被包装,那么它应该是包装。如果不需要包装,那么不包装就没有危害。如果你不确定或不能说明,那么最安全的做法就是让它们保持原样。

作为指导来做出该确定(你应该决定继续进行),其中要求或建议记录填料情况包括:

  • 记录的持续值
  • 共享记录值与[潜在]不同的编译代码
  • 与外部定义的结构
  • 在不同结构的存储器故意重叠一个类型的布局严格兼容性

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

  • 记录包括必须和可以经任何潜在生产者或消费者依靠相邻字节一系列值没有从编译器的干扰或其他因素的可能性记录的

我会建议是,(如果可能的话和实际),你确定是什么目的的包装供应在每种情况下并为此目的添加文档的记录声明本身,以便任何人在未来的相同问题不会必须要经过发现过程,例如:

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; 
+0

+1优秀的答案 –

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

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

+7

+1。除非您有完整的回归测试可用,否则不要乱用遗留代码。 –

如果记录以包装形式存储/检索或以任何方式转移到希望打包的接收方,那么不要更改它。

更新:

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

+0

这些记录主要用于存储一些信息,并在程序中将它们在不同的类中传递,而不是。可能有一部分代码依赖于每个字节的实际顺序,但我知道并非每个记录都需要打包 – Earlz

+1

无论如何,最好不要触摸打包的声明。没有收获,只有忽略为什么它被宣布为这样的一些重要原因的风险。 –

+0

由于缺乏“重要原因”,可能会有一个“副作用”,不容易说明。 –

  • 盒装记录具有长度相同的部件恰好大小。
  • 没有打包的记录被优化(对齐 - >因此更高)以获得更好的性能。