NSArchiver 与 NSKeyedArchiver 性能对比
Posted
技术标签:
【中文标题】NSArchiver 与 NSKeyedArchiver 性能对比【英文标题】:NSArchiver vs NSKeyedArchiver performance 【发布时间】:2012-02-07 01:09:06 【问题描述】:为什么 NSKeyedArchiver 的性能这么差?与使用 NSArchiver 相比,大小翻倍。
我正在使用以下行编码一个 NSMutableArray 对象
BOOL result = [NSArchiver archiveRootObject:self.appDataObject.materias toFile:archivePath];
NSMutableArray 包含具有相应 encodeWithCoder 和 initWithCoder 的自定义对象
-(void)encodeWithCoder:(NSCoder *)aCoder
[aCoder encodeObject: _fileName];
[aCoder encodeObject: _categoria];
[aCoder encodeObject: _materia];
[aCoder encodeObject: _nombre];
[aCoder encodeObject: _position];
[aCoder encodeValueOfObjCType:@encode(BOOL) at:&_favorite];
-(id)initWithCoder:(NSCoder *)aDecoder
if (self=[super init])
[self setFileName:[aDecoder decodeObject]];
[self setCategoria:[aDecoder decodeObject]];
[self setMateria:[aDecoder decodeObject]];
[self setNombre:[aDecoder decodeObject]];
[self setPosition:[aDecoder decodeObject]];
[aDecoder decodeValueOfObjCType:@encode(BOOL) at:&_favorite];
return self;
它工作正常,因为它可以正确保存文件,然后我可以取消归档它。它们大约有 3000 个对象,输出文件约为 900kB
当我将归档行更改为:
BOOL result = [NSKeyedArchiver archiveRootObject:self.appDataObject.materias toFile:archivePath];
一切都很神奇但是文件大小增加了一倍以上,达到 2MB!
我为什么要问这个?因为我正在开发一个 ios 应用程序,因此失去了对 NSArchiver 的支持。
【问题讨论】:
【参考方案1】:至于尺寸减小,我认为这与 NSKeyedArchiver 存储引用而不是实际值有关。
我比较了 NSKeyedArchiver 和 NSArchiver,以及一个基于 cocotron 的名为 NSKeylessArchiver 的新类(由于私有 API 状态,NSArchiver 在 iOS 上可能是禁止使用的)。 NSKeylessArchiver 使用引用来减少具有重复字符串或对象的数据的大小,并且如果您不需要键,则可以更快地解码。
没有子对象和 20000 个整数的简单根对象的性能:
| |encoding (min/max/avg secs)|decoding (min/max/avg secs)|
|-----------------|:-------------------------:|:-------------------------:|
|NSKeyedArchiver | 0.2048/0.2453/0.2165 | 6.8919/6.9238/6.9037|
|NSKeylessArchiver| 0.0407/0.0506/0.0451 | 0.0253/0.0330/0.0287|
|NSArchiver | 0.0094/0.0114/0.0102 | 0.0019/0.0025/0.0020|
更多详情,请参阅Github repo 和blog post。
【讨论】:
【参考方案2】:我知道这个线程很旧,但你我想考虑使用 NSPropertyListSerialization...
看看这个线程中提到的性能差异: http://www.cocoabuilder.com/archive/cocoa/2221-nspropertylistserialization-vs-nskeyedarchiver-performance.html
【讨论】:
【参考方案3】:您获得了向前和向后的兼容性。它是键控,这意味着存档必须存储更多信息才能进行键控查找。请参阅此处的参考:Archives and Serialization
【讨论】:
是的,我了解 NSKeyedArchiver 的优点,但如果我不需要向后兼容怎么办?只需要性能?在这个例子中,我什至没有使用键,对象仍然按顺序保存,使用相同的编码器,我只使用“键控”命令,但仍然保存旧方式。该文件在 Iphone 中加载需要超过 15 秒,这对于用户体验来说是很多的。 您是否考虑过替代存储技术,例如代码数据?您是否需要同时提供所有 3000 个对象,或者您可以分页或分块访问它们? 我选择了 NSArchiver,因为它很简单。 NSPropertyListSerialization 不允许自定义对象。而且我不断地查询超过 3000 个项目,所以它们必须在内存中。不记得为什么我停止使用 Core Data,它通常比 Archiver 更有效吗? 如果您不断地查询 3000 个项目,您应该使用 CoreData 还是在活动内存中保留 3000 个项目以外的其他东西?以上是关于NSArchiver 与 NSKeyedArchiver 性能对比的主要内容,如果未能解决你的问题,请参考以下文章