Delphi如何高效序列化类指定字段生成仅含Name和Flags的JSON
如何获取仅包含Name和Flags字段的JSON
问题背景
现有如下TUser类定义:
TUser = class private FName: string; FFlags: UInt32; FFields: UInt32; FCreated: TDateTime; public property Name: string read FName write FName; property Flags: UInt32 read FFlags write FFlags; property Fields: UInt32 read FFields write FFields; property Created: TDateTime read FCreated write FCreated; constructor Create; end;
常规场景下会序列化类的全部公开属性,用法如下:
var User: TUser sJson: string; sJson := User.AsJson;
当仅需要输出包含Name和Flags两个字段的JSON时,目前的实现是先全量序列化整个对象,再移除多余字段:
var User: TUser usr: ISuperObject; sJson: string; usr := SO(User.AsJson); usr.Remove('Fields'); usr.Remove('Created'); sJson := usr.AsJSON;
该实现效率较低:实际业务中类共有15个字段,需要移除其中12个,需要更高效的实现方案。
更新疑问:如下手动构造目标JSON的方法,是否更快速、更实用?
usr := SO(''); usr.S['Name'] := User.Name; usr.I['Flags'] := User.Flags; sJson := usr.AsJSON;
解答
你提到的手动构造仅包含目标字段的JSON对象的方案,比先全量序列化再删字段的方式效率高很多,完全实用。
这种实现的性能优势很明确:
- 省去了12个非必要字段的序列化开销,尤其是当字段包含日期格式转换、复杂嵌套对象、大文本内容时,这部分开销占比极高
- 省去了全量JSON字符串的解析、多余字段删除的额外操作,内存占用也更低
如果后续需要频繁输出不同字段组合的JSON,还可以选择更易维护的实现:
- 借助序列化库的忽略标记:你当前使用的SuperObject库支持
[Transient]属性标记,给不需要默认序列化的字段加上该标记后,默认调用AsJson时会自动跳过这些字段。如果全量序列化的场景也很多,可以给类扩展多个序列化辅助方法,分别对应不同字段组合的输出需求。 - 高频场景下直接拼接JSON:如果这个两字段序列化的逻辑调用频率极高,可以直接做字符串拼接,性能是所有方案里最高的,只需要注意对
Name字段的双引号做转义即可:
这种方案不需要创建JSON对象实例,没有额外的构造、解析开销。sJson := Format('{"Name":"%s","Flags":%d}', [StringReplace(User.Name, '"', '\"', [rfReplaceAll]), User.Flags]);
内容的提问来源于stack exchange,提问作者Alex Egorov
相关产品推荐
相关产品推荐

